[open-ils-commits] [GIT] Evergreen ILS branch master updated. 585cb6eda514ffa3d335c6bcbd481c682027faee

Evergreen Git git at git.evergreen-ils.org
Mon Apr 2 11:38:14 EDT 2012


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  585cb6eda514ffa3d335c6bcbd481c682027faee (commit)
       via  4d1b0959a3a75abe20f594298289e948dd9144a4 (commit)
       via  2c729df6fa6769f050ac27c0ab234aa3abcea5be (commit)
       via  18398232025f14f40237954bdf0ff959366636ff (commit)
       via  2c12f39fc60a2454936bc54d6ed7926f0df646ae (commit)
       via  990df40fceb4e73dc529727b74f07443fe45163f (commit)
       via  e86cd48a46461341d8b8ad2d18e9c64b98cf3b8f (commit)
       via  f1215a0ba81bb09b08b98c81672fb4b9534eaa5e (commit)
       via  4a28c176b5ed10fc76a4831fc8bce3751dc8760b (commit)
       via  dd20011fc24a1820ba80606e153e301986d15df2 (commit)
       via  463d1af0d851db146f1b3d5da8ed3f1e14f9790c (commit)
       via  ac21f2eb4f45103acafa89513fb92e49a6efc5b4 (commit)
       via  234758498708a82c024f2af26720ebea5b77cd89 (commit)
       via  f7522f2e0b631c92c9d1fb2efcaed4e54090a379 (commit)
       via  3be0d23c88cc5db64002cb2f7d877116d5c13242 (commit)
       via  75bdd9b0d70ff7010106210ec2349041e41a08cd (commit)
       via  53ab5197ecf61923e28f69c58d79cc4c56196e21 (commit)
       via  5c86f181a70433399a30f85a1be3a4da145d60a6 (commit)
       via  f894f96cc00d99d7a164be748d85f661d9e24b97 (commit)
       via  fa24df6e6d59cc052ca9ea38caaaa19a0096654d (commit)
       via  a489e2d4d26938be04e7a56e382967252b03e652 (commit)
      from  a388ac83c59040b9f451ea2651474859b0b3a40b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 585cb6eda514ffa3d335c6bcbd481c682027faee
Author: Thomas Berezansky <tsbere at mvlc.org>
Date:   Mon Apr 2 11:37:10 2012 -0400

    Stamping Stat Cat Enhancements upgrade script
    
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql
index 58d8db7..34224b1 100644
--- a/Open-ILS/src/sql/Pg/002.schema.config.sql
+++ b/Open-ILS/src/sql/Pg/002.schema.config.sql
@@ -87,7 +87,7 @@ CREATE TRIGGER no_overlapping_deps
     BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
     FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
 
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0700', :eg_version); -- senator/dbwells/miker
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0701', :eg_version); -- sprater/bshum/tsbere
 
 CREATE TABLE config.bib_source (
 	id		SERIAL	PRIMARY KEY,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.patron_stat_category_enhancements.sql b/Open-ILS/src/sql/Pg/upgrade/0701.schema.patron_stat_category_enhancements.sql
similarity index 94%
rename from Open-ILS/src/sql/Pg/upgrade/XXXX.schema.patron_stat_category_enhancements.sql
rename to Open-ILS/src/sql/Pg/upgrade/0701.schema.patron_stat_category_enhancements.sql
index 01f28fb..191b84a 100644
--- a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.patron_stat_category_enhancements.sql
+++ b/Open-ILS/src/sql/Pg/upgrade/0701.schema.patron_stat_category_enhancements.sql
@@ -1,4 +1,4 @@
--- Evergreen DB patch XXXX.schema.patron_stat_category_enhancements.sql
+-- Evergreen DB patch 0701.schema.patron_stat_category_enhancements.sql
 --
 -- Enables users to set patron statistical categories as required,
 -- whether or not users can input free text for the category value.
@@ -8,7 +8,7 @@
 BEGIN;
 
 -- check whether patch can be applied
-SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+SELECT evergreen.upgrade_deps_block_check('0701', :eg_version);
 
 -- New table
 

commit 4d1b0959a3a75abe20f594298289e948dd9144a4
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Feb 28 13:43:00 2012 -0600

    Patron Stat Cat Enhancements: SQL upgrade statements
    
    Add SQL upgrade statements:  new table stat_cat_entry_default,
    new columns 'required' and 'allow_freetext' on actor.stat_cat,
    and new permissions to create, delete default entries.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.patron_stat_category_enhancements.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.patron_stat_category_enhancements.sql
new file mode 100644
index 0000000..01f28fb
--- /dev/null
+++ b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.patron_stat_category_enhancements.sql
@@ -0,0 +1,62 @@
+-- Evergreen DB patch XXXX.schema.patron_stat_category_enhancements.sql
+--
+-- Enables users to set patron statistical categories as required,
+-- whether or not users can input free text for the category value.
+-- Enables administrators to set an entry as the default for any
+-- given patron statistical category and org unit.
+--
+BEGIN;
+
+-- check whether patch can be applied
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+-- New table
+
+CREATE TABLE actor.stat_cat_entry_default (
+    id              SERIAL  PRIMARY KEY,
+    stat_cat_entry  INT     NOT NULL REFERENCES actor.stat_cat_entry (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    stat_cat        INT     NOT NULL REFERENCES actor.stat_cat (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    owner           INT     NOT NULL REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+    CONSTRAINT sced_once_per_owner UNIQUE (stat_cat,owner)
+);
+
+COMMENT ON TABLE actor.stat_cat_entry_default IS $$
+User Statistical Category Default Entry
+
+A library may choose one of the stat_cat entries to be the
+default entry.
+$$;
+
+-- Add columns to existing tables
+
+-- Patron stat cat required column
+ALTER TABLE actor.stat_cat
+    ADD COLUMN required BOOL NOT NULL DEFAULT FALSE;
+
+-- Patron stat cat allow_freetext column
+ALTER TABLE actor.stat_cat
+    ADD COLUMN allow_freetext BOOL NOT NULL DEFAULT TRUE;
+
+-- Add permissions
+
+INSERT INTO permission.perm_list ( id, code, description ) VALUES
+    ( 525, 'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT', oils_i18n_gettext( 525, 
+        'User may set a default entry in a patron statistical category', 'ppl', 'description' )),
+    ( 526, 'UPDATE_PATRON_STAT_CAT_ENTRY_DEFAULT', oils_i18n_gettext( 526, 
+        'User may reset a default entry in a patron statistical category', 'ppl', 'description' )),
+    ( 527, 'DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT', oils_i18n_gettext( 527, 
+        'User may unset a default entry in a patron statistical category', 'ppl', 'description' ));
+
+INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
+    SELECT
+        pgt.id, perm.id, aout.depth, TRUE
+    FROM
+        permission.grp_tree pgt,
+        permission.perm_list perm,
+        actor.org_unit_type aout
+    WHERE
+        pgt.name = 'Circulation Administrator' AND
+        aout.name = 'System' AND
+        perm.code IN ('CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT', 'DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT');
+
+COMMIT;

commit 2c729df6fa6769f050ac27c0ab234aa3abcea5be
Author: Scott Prater <sprater at gmail.com>
Date:   Wed Mar 21 21:44:23 2012 -0500

    Patron Stat Cat Enhancements: Only show default entry for new patrons
    
    Only display the default entry when registering new patrons.
    Otherwise, display the saved value for the patron or nothing.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/web/js/ui/default/actor/user/register.js b/Open-ILS/web/js/ui/default/actor/user/register.js
index 765467e..dd0a735 100644
--- a/Open-ILS/web/js/ui/default/actor/user/register.js
+++ b/Open-ILS/web/js/ui/default/actor/user/register.js
@@ -860,11 +860,11 @@ function loadStatCats() {
         sc_widget._wtype = 'statcat';
         sc_widget._statcat = stat.id();
 
-        // set default value:  first choice is patron table entry,
-        // then the default entry for the stat_cat
+        // set value:  first choice is patron table entry,
+        // then the default entry for the stat_cat if new patron
         if(patmap) {
             sc_widget.attr(p_opt, patmap.stat_cat_entry()); 
-        } else if(entrymap) {
+        } else if(entrymap && patron.isnew()) {
             sc_widget.attr('value', e_field); 
         }
 

commit 18398232025f14f40237954bdf0ff959366636ff
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Feb 28 10:22:29 2012 -0600

    Patron Stat Cat Enhancements: Rearrange stat cat editor screen
    
    Rearrange the statistical categories editor interface to correctly
    display the "Archived" radio buttons along side the other radio
    buttons.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
index 7264269..1f50f31 100644
--- a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
+++ b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
@@ -88,13 +88,6 @@
                             <span>&staff.server.admin.stat_cat.off;</span>
                             <input type='radio' name='required' checked='checked'> </input>
                         </td>
-                        <td id='usr_summary_td1'>&staff.server.admin.stat_cat.usr_summary;</td>
-                        <td id='usr_summary_td2'>    
-                            <span>&staff.server.admin.stat_cat.on;</span>
-                            <input type='radio' name='usr_summary' id='sc_make_usr_summary'> </input>
-                            <span>&staff.server.admin.stat_cat.off;</span>
-                            <input type='radio' name='usr_summary' checked='checked'> </input>
-                        </td>
                         <td>&staff.server.admin.stat_cat.checkout_archive;</td>
                         <td>
                             <span>&staff.server.admin.stat_cat.on;</span>
@@ -111,6 +104,13 @@
                             <span>&staff.server.admin.stat_cat.off;</span>
                             <input type='radio' name='usr_freetext'> </input>
                         </td>
+                        <td id='usr_summary_td1'>&staff.server.admin.stat_cat.usr_summary;</td>
+                        <td id='usr_summary_td2'>    
+                            <span>&staff.server.admin.stat_cat.on;</span>
+                            <input type='radio' name='usr_summary' id='sc_make_usr_summary'> </input>
+                            <span>&staff.server.admin.stat_cat.off;</span>
+                            <input type='radio' name='usr_summary' checked='checked'> </input>
+                        </td>
                     </tr>
                     <tr>
                         <td>&staff.server.admin.stat_cat.sip_field;</td>

commit 2c12f39fc60a2454936bc54d6ed7926f0df646ae
Author: Scott Prater <sprater at gmail.com>
Date:   Wed Feb 15 21:28:46 2012 -0600

    Patron Stat Cat Enhancements: Fix values stored, then displayed in "Allow freetext" categories
    
    In the patron registration screen:  the widget dijit.form.FilteringSelect
    stores the option value, not the displayed value, unlike ComboBox; so store
    the FilteringSelect displayedValue, then set the FilteringSelect displayedValue
    with the value retrieved from the patron/stat_cat_entry map table.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/web/js/ui/default/actor/user/register.js b/Open-ILS/web/js/ui/default/actor/user/register.js
index 523639b..765467e 100644
--- a/Open-ILS/web/js/ui/default/actor/user/register.js
+++ b/Open-ILS/web/js/ui/default/actor/user/register.js
@@ -816,6 +816,10 @@ function loadStatCats() {
         var stat = statCats[idx];
         var required = openils.Util.isTrue(stat.required());
         var allow_freetext = openils.Util.isTrue(stat.allow_freetext());
+        var default_entry = null;
+        if(stat.default_entries()[0])
+            default_entry = stat.default_entries()[0].stat_cat_entry();
+        
         var row = statCatTemplate.cloneNode(true);
         row.id = 'stat-cat-row-' + idx;
         row.setAttribute('stat_cat_owner',stat.owner());
@@ -832,21 +836,22 @@ function loadStatCats() {
         var span = valtd.appendChild(document.createElement('span'));
         var store = new dojo.data.ItemFileReadStore(
                 {data:fieldmapper.actsc.toStoreData(stat.entries())});
+        var p_opt, e_field;
 
+        var patmap = patron.stat_cat_entries().filter(
+            function(mp) { return (mp.stat_cat() == stat.id()) })[0];
+        var entrymap = stat.entries().filter(
+                function(mp) { return (mp.id() == default_entry) })[0];
+        
         if(allow_freetext) {
             sc_widget = new dijit.form.ComboBox({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
+	    e_field = entrymap ? entrymap.value() : null;
+	    p_opt = 'value';
         } else {
             sc_widget = new dijit.form.FilteringSelect({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
-        }
-
-        if(required) {
-            sc_widget.isValid = function() {
-                // Must contain a word character
-                if(this.attr("value").match(/\w/)) {
-                    return true;
-                } else return false;
-            };
-            sc_widget.attr('required', true);
+            sc_widget.attr('required', false);
+	    e_field = entrymap ? entrymap.id() : null;
+	    p_opt = 'displayedValue';
         }
 
         sc_widget.labelAttr = 'value';
@@ -855,14 +860,20 @@ function loadStatCats() {
         sc_widget._wtype = 'statcat';
         sc_widget._statcat = stat.id();
 
-        // populate existing cats
-        var map = patron.stat_cat_entries().filter(
-            function(mp) { return (mp.stat_cat() == stat.id()) })[0];
-        if(map) sc_widget.attr('value', map.stat_cat_entry()); 
-        
-        sc_widget._hasBeenBlurred = true;
-                if(sc_widget.validate)
-                    sc_widget.validate();
+        // set default value:  first choice is patron table entry,
+        // then the default entry for the stat_cat
+        if(patmap) {
+            sc_widget.attr(p_opt, patmap.stat_cat_entry()); 
+        } else if(entrymap) {
+            sc_widget.attr('value', e_field); 
+        }
+
+        if(required) {
+            sc_widget.attr('required', true);
+            sc_widget._hasBeenBlurred = true;
+            if(sc_widget.validate)
+                sc_widget.validate();
+        }
 
         widgetPile.push(sc_widget); 
     }
@@ -1768,6 +1779,10 @@ function _uEditSave(doClone) {
                     function(m){
                         return (m.stat_cat() == w._statcat) })[0];
 
+                if(w.declaredClass == 'dijit.form.FilteringSelect') {
+                    val = w.attr('displayedValue');
+                }
+
                 if(map) {
                     if(map.stat_cat_entry() == val) 
                         break;

commit 990df40fceb4e73dc529727b74f07443fe45163f
Author: Scott Prater <sprater at gmail.com>
Date:   Wed Jan 18 14:30:00 2012 -0600

    Patron Stat Cat Enhancements: Enforce stat_cat "allow_freetext" flag in patron registration screen
    
    If a patron statistical category is flagged to disallow user-provided
    entries, make the category form field a FilteringSelect box;  otherwise,
    make it a ComboBox.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/web/js/ui/default/actor/user/register.js b/Open-ILS/web/js/ui/default/actor/user/register.js
index bcdf18b..523639b 100644
--- a/Open-ILS/web/js/ui/default/actor/user/register.js
+++ b/Open-ILS/web/js/ui/default/actor/user/register.js
@@ -804,6 +804,7 @@ function loadAllAddrs() {
 }
 
 function loadStatCats() {
+    var sc_widget;
 
     statCats = fieldmapper.standardRequest(
         ['open-ils.circ', 'open-ils.circ.stat_cat.actor.retrieve.all'],
@@ -814,6 +815,7 @@ function loadStatCats() {
     for(var idx in statCats) {
         var stat = statCats[idx];
         var required = openils.Util.isTrue(stat.required());
+        var allow_freetext = openils.Util.isTrue(stat.allow_freetext());
         var row = statCatTemplate.cloneNode(true);
         row.id = 'stat-cat-row-' + idx;
         row.setAttribute('stat_cat_owner',stat.owner());
@@ -830,32 +832,39 @@ function loadStatCats() {
         var span = valtd.appendChild(document.createElement('span'));
         var store = new dojo.data.ItemFileReadStore(
                 {data:fieldmapper.actsc.toStoreData(stat.entries())});
-        var comboBox = new dijit.form.ComboBox({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
+
+        if(allow_freetext) {
+            sc_widget = new dijit.form.ComboBox({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
+        } else {
+            sc_widget = new dijit.form.FilteringSelect({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
+        }
+
         if(required) {
-            comboBox.isValid = function() {
+            sc_widget.isValid = function() {
                 // Must contain a word character
                 if(this.attr("value").match(/\w/)) {
                     return true;
                 } else return false;
             };
-            comboBox.attr('required', true);
+            sc_widget.attr('required', true);
         }
-        comboBox.labelAttr = 'value';
-        comboBox.searchAttr = 'value';
 
-        comboBox._wtype = 'statcat';
-        comboBox._statcat = stat.id();
+        sc_widget.labelAttr = 'value';
+        sc_widget.searchAttr = 'value';
+
+        sc_widget._wtype = 'statcat';
+        sc_widget._statcat = stat.id();
 
         // populate existing cats
         var map = patron.stat_cat_entries().filter(
             function(mp) { return (mp.stat_cat() == stat.id()) })[0];
-        if(map) comboBox.attr('value', map.stat_cat_entry()); 
+        if(map) sc_widget.attr('value', map.stat_cat_entry()); 
         
-        comboBox._hasBeenBlurred = true;
-                if(comboBox.validate)
-                    comboBox.validate();
+        sc_widget._hasBeenBlurred = true;
+                if(sc_widget.validate)
+                    sc_widget.validate();
 
-        widgetPile.push(comboBox); 
+        widgetPile.push(sc_widget); 
     }
 }
 

commit e86cd48a46461341d8b8ad2d18e9c64b98cf3b8f
Author: Scott Prater <sprater at gmail.com>
Date:   Wed Jan 18 13:57:44 2012 -0600

    Patron Stat Cat Enhancements: Enforce stat_cat "required" flag in patron registration screen
    
    If a patron statistical category is flagged as required, make
    the category form field a required field, and validate it before
    submitting the form.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/web/js/ui/default/actor/user/register.js b/Open-ILS/web/js/ui/default/actor/user/register.js
index 1ed56a4..bcdf18b 100644
--- a/Open-ILS/web/js/ui/default/actor/user/register.js
+++ b/Open-ILS/web/js/ui/default/actor/user/register.js
@@ -813,11 +813,17 @@ function loadStatCats() {
     // draw stat cats
     for(var idx in statCats) {
         var stat = statCats[idx];
+        var required = openils.Util.isTrue(stat.required());
         var row = statCatTemplate.cloneNode(true);
         row.id = 'stat-cat-row-' + idx;
         row.setAttribute('stat_cat_owner',stat.owner());
         row.setAttribute('stat_cat_name',stat.name());
         row.setAttribute('stat_cat_id',stat.id());
+        if(required) {
+            row.setAttribute('required','required');
+            dividerRow = dojo.byId('stat-cat-divider');
+            dividerRow.setAttribute('required','required');
+        }
         tbody.appendChild(row);
         getByName(row, 'name').innerHTML = stat.name();
         var valtd = getByName(row, 'widget');
@@ -825,18 +831,31 @@ function loadStatCats() {
         var store = new dojo.data.ItemFileReadStore(
                 {data:fieldmapper.actsc.toStoreData(stat.entries())});
         var comboBox = new dijit.form.ComboBox({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
+        if(required) {
+            comboBox.isValid = function() {
+                // Must contain a word character
+                if(this.attr("value").match(/\w/)) {
+                    return true;
+                } else return false;
+            };
+            comboBox.attr('required', true);
+        }
         comboBox.labelAttr = 'value';
         comboBox.searchAttr = 'value';
 
         comboBox._wtype = 'statcat';
         comboBox._statcat = stat.id();
-        widgetPile.push(comboBox); 
 
         // populate existing cats
         var map = patron.stat_cat_entries().filter(
             function(mp) { return (mp.stat_cat() == stat.id()) })[0];
         if(map) comboBox.attr('value', map.stat_cat_entry()); 
+        
+        comboBox._hasBeenBlurred = true;
+                if(comboBox.validate)
+                    comboBox.validate();
 
+        widgetPile.push(comboBox); 
     }
 }
 

commit f1215a0ba81bb09b08b98c81672fb4b9534eaa5e
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 16:19:20 2011 -0600

    Patron Stat Cat Enhancements: Modify stat cat editor HTML to manipulate patron stat cat default entries.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
index f644cae..7264269 100644
--- a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
+++ b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
@@ -284,15 +284,20 @@
             </tr>
 
             <tr class='insert_row' id='sc_edit_entry_row'>
-                <td colspan='7'>
+                <td colspan='11'>
                     <span class='padded'>
                         <span>&staff.server.admin.stat_cat.edit_entry_owner;</span><b name='sc_edit_entry_owner'/>
                     </span>
                     <span class='padded'>
                         <input type='text' name='sc_edit_entry_name' class='padded'/>
                     </span>
+                    <span class='hide_me' name='sc_edit_entry_default'>
+                        <input type='checkbox' name='sc_edit_entry_default_set'/>
+                        &staff.server.admin.stat_cat.set_default_entry;
+                        <select name='sc_edit_entry_default_lib'> </select>
+                    </span>
                     <span class='padded'>
-                        <input type='submit' name='sc_edit_entry_name_submit' value='&staff.server.admin.stat_cat.edit_entry_name_submit;' class='padded'/>
+                        <input type='submit' name='sc_edit_entry_submit' value='&staff.server.admin.stat_cat.edit_entry_submit;' class='padded'/>
                     </span>
                     <span class='padded'>
                         <input type='submit' name='sc_edit_entry_delete' value='&staff.server.admin.stat_cat.edit_entry_delete;' class='padded'/>
@@ -304,7 +309,7 @@
             </tr>
 
             <tr class='insert_row' id='sc_new_entry_row'>
-                <td colspan='7'> 
+                <td colspan='11'> 
                     <span>&staff.server.admin.stat_cat.new_entry_name;</span>
                     <span class='padded'>
                         <input type='text' name='sc_new_entry_name'/>
@@ -312,6 +317,11 @@
                     <span class='padded'>
                         <select name='sc_new_entry_lib'> </select>
                     </span>
+                    <span class='hide_me' name='sc_new_entry_default'>
+                        <input type='checkbox' name='sc_new_entry_default_set'/>
+                        &staff.server.admin.stat_cat.set_default_entry;
+                        <select name='sc_new_entry_default_lib'> </select>
+                    </span>
                     <span class='padded'>
                         <input type='submit' name='sc_new_entry_create' value='&staff.server.admin.stat_cat.new_entry_create;'/>
                     </span>

commit 4a28c176b5ed10fc76a4831fc8bce3751dc8760b
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 16:17:35 2011 -0600

    Patron Stat Cat Enhancements: Modify stat cat editor javascript to manipulate patron stat cat default entries.
    
    Add functions, methods, variables to Statistical Categories Editor
    javascript to manage patron stat cat default entries.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js
index eee8022..ae8f327 100644
--- a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js
+++ b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js
@@ -6,6 +6,8 @@ var SC_DELETE            = 'open-ils.circ:open-ils.circ.stat_cat.TYPE.delete';
 var SC_ENTRY_CREATE    = 'open-ils.circ:open-ils.circ.stat_cat.TYPE.entry.create';
 var SC_ENTRY_UPDATE    = 'open-ils.circ:open-ils.circ.stat_cat.TYPE.entry.update';
 var SC_ENTRY_DELETE    = 'open-ils.circ:open-ils.circ.stat_cat.TYPE.entry.delete';
+var SC_ENTRY_DEFAULT_CREATE    = 'open-ils.circ:open-ils.circ.stat_cat.actor.entry.default.create';
+var SC_ENTRY_DEFAULT_DELETE    = 'open-ils.circ:open-ils.circ.stat_cat.actor.entry.default.delete';
 
 var ACTOR                = 'actor';
 var ASSET                = 'asset';
@@ -35,6 +37,9 @@ var myPerms = [
     'CREATE_PATRON_STAT_CAT_ENTRY',
     'UPDATE_PATRON_STAT_CAT_ENTRY',
     'DELETE_PATRON_STAT_CAT_ENTRY',
+    'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT',
+    'UPDATE_PATRON_STAT_CAT_ENTRY_DEFAULT',
+    'DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT',
 
     'CREATE_COPY_STAT_CAT',
     'UPDATE_COPY_STAT_CAT',
@@ -51,6 +56,9 @@ function scSetPerms() {
     PERMS[ACTOR].create_stat_cat_entry = OILS_WORK_PERMS.CREATE_PATRON_STAT_CAT_ENTRY;
     PERMS[ACTOR].update_stat_cat_entry = OILS_WORK_PERMS.UPDATE_PATRON_STAT_CAT_ENTRY;
     PERMS[ACTOR].delete_stat_cat_entry = OILS_WORK_PERMS.DELETE_PATRON_STAT_CAT_ENTRY;
+    PERMS[ACTOR].create_stat_cat_default_entry = OILS_WORK_PERMS.CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT;
+    PERMS[ACTOR].update_stat_cat_default_entry = OILS_WORK_PERMS.UPDATE_PATRON_STAT_CAT_ENTRY_DEFAULT;
+    PERMS[ACTOR].delete_stat_cat_default_entry = OILS_WORK_PERMS.DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT;
 
     PERMS[ASSET].create_stat_cat = OILS_WORK_PERMS.CREATE_COPY_STAT_CAT;
     PERMS[ASSET].update_stat_cat = OILS_WORK_PERMS.UPDATE_COPY_STAT_CAT;
@@ -178,6 +186,7 @@ function scDraw( type, cats ) {
 var scEntryCounter;
 function scInsertCat( tbody, cat, type ) {
 
+    var default_entry_id = -1;
     var row = scRow.cloneNode(true);
     row.id = 'sc_tr_' + cat.id();
     var required = cat.required();
@@ -241,14 +250,31 @@ function scInsertCat( tbody, cat, type ) {
         }
     );
 
-    for( var e in cat.entries() ) 
-        scInsertEntry( cat, cat.entries()[e], $n(row, 'sc_entries_selector'), tbody, type );
+    for( var e in cat.entries() ) { 
+        if (scInsertEntry( cat, cat.entries()[e], $n(row, 'sc_entries_selector'), tbody, type ))
+            default_entry_id =  cat.entries()[e].id();
+    }
+    
+    if (default_entry_id > 0)
+        setSelector($n(row, 'sc_entries_selector'), default_entry_id);
 }
 
 
 function scInsertEntry( cat, entry, selector, tbody, type ) {
-    setSelectorVal( selector, scEntryCounter++, entry.value(), entry.id(), 
+    var val = entry.value();
+    var entry_id = entry.id();
+    var is_default_entry = false;
+
+    if(type == ACTOR) {
+        if( cat.default_entries()[0] && cat.default_entries()[0].stat_cat_entry() == entry_id ) {
+            val = val + "*";
+            is_default_entry = true;
+        }
+    }
+    setSelectorVal( selector, scEntryCounter++, val, entry_id, 
             function(){ scUpdateEntry( cat, entry, tbody, type );} );
+
+    return is_default_entry;
 }
 
 
@@ -275,6 +301,15 @@ function scCreateEntry( type, id, row ) {
     entry.owner(getSelectorVal($n(row, 'sc_new_entry_lib')));
     entry.value(value);
 
+         
+    var default_entry;
+    if ( type == ACTOR && $n(row, 'sc_new_entry_default_set').checked ) {
+        default_entry = new actsced();
+        default_entry.isnew(1);
+        default_entry.stat_cat(id);
+        default_entry.owner(getSelectorVal($n(row, 'sc_new_entry_default_lib')));
+        entry.default_entries([default_entry]);
+    }
     var req = new Request( SC_ENTRY_CREATE.replace(/TYPE/, type), session, entry );
     req.send(true);
     var res = req.result();
@@ -292,6 +327,12 @@ function scNewEntry( type, cat, tbody ) {
     if(r.nextSibling) tbody.insertBefore( row, r.nextSibling );
     else{ tbody.appendChild(row); }
 
+    if(type == ACTOR) {
+        unHideMe($n(row, 'sc_new_entry_default'));
+    } else {
+        hideMe($n(row, 'sc_new_entry_default'));
+    }
+
     $n(row, 'sc_new_entry_create').onclick = 
         function() {
             if( scCreateEntry( type, cat.id(), row ) )
@@ -302,6 +343,8 @@ function scNewEntry( type, cat, tbody ) {
     if(org_list.length == 0) {
         $n(row, 'sc_new_entry_create').disabled = true;
         $n(row, 'sc_new_entry_lib').disabled = true;
+        if (type==ACTOR)
+            $n(row, 'sc_new_entry_default_lib').disabled = true;
         return;
     }
 
@@ -309,9 +352,12 @@ function scNewEntry( type, cat, tbody ) {
     if(!rootOrg) {
         $n(row, 'sc_new_entry_create').disabled = true;
         $n(row, 'sc_new_entry_lib').disabled = true;
+        if (type==ACTOR)
+            $n(row, 'sc_new_entry_default_lib').disabled = true;
         return;
     }
     buildOrgSel($n(row, 'sc_new_entry_lib'), rootOrg, 0, 'shortname');
+    buildOrgSel($n(row, 'sc_new_entry_default_lib'), rootOrg, 0, 'shortname');
     $n(row, 'sc_new_entry_name').focus();
 }
 
@@ -523,15 +569,25 @@ function scUpdateEntry( cat, entry, tbody, type ) {
     else{ tbody.appendChild(row); }
 
     $n(row, 'sc_edit_entry_owner').appendChild(text(findOrgUnit(entry.owner()).name()));
+    
+    var defaultentry = $n(row, 'sc_edit_entry_default_set');
+    if(type == ACTOR) {
+        unHideMe($n(row, 'sc_edit_entry_default'));
+        if( cat.default_entries()[0] && cat.default_entries()[0].stat_cat_entry() == entry.id() )
+            defaultentry.checked =  true;
+    } else {
+        hideMe($n(row, 'sc_edit_entry_default'));
+    }
 
     var name = $n(row, 'sc_edit_entry_name');
     name.value = entry.value();
+    name.value.replace(/\*$/, "");
     name.focus();
     name.select();
 
-    $n(row,'sc_edit_entry_name_submit').onclick = 
+    $n(row,'sc_edit_entry_submit').onclick = 
         function(){
-            if( scEditEntry(cat, entry, name.value, type ) )
+            if( scEditEntry(cat, entry, row, type ) )
                 tbody.removeChild(row);
             };
 
@@ -541,12 +597,23 @@ function scUpdateEntry( cat, entry, tbody, type ) {
 
     var rootEditOrg = findReleventRootOrg(PERMS[type].update_stat_cat_entry, entry.owner());
     var rootDelOrg = findReleventRootOrg(PERMS[type].delete_stat_cat_entry, entry.owner());
+    var org_list = PERMS[type].update_stat_cat_entry;
 
     if(!rootEditOrg || rootEditOrg.id() != entry.owner())
         $n(row,'sc_edit_submit').disabled = true;
 
     if(!rootDelOrg || rootDelOrg.id() != entry.owner())
         $n(row,'sc_edit_delete').disabled = true;
+
+    if(type == ACTOR) {
+        if(!rootEditOrg || org_list.length == 0) {
+            $n(row, 'sc_edit_entry_default_lib').disabled = true;
+            return;
+        }
+        buildOrgSel($n(row, 'sc_edit_entry_default_lib'), rootEditOrg, 0, 'shortname');
+        if( cat.default_entries()[0] )
+           setSelector( $n(row, 'sc_edit_entry_default_lib'), cat.default_entries()[0].owner() );
+    }
 }
 
 function scEntryDelete( cat, entry, type ) {
@@ -559,14 +626,69 @@ function scEntryDelete( cat, entry, type ) {
     scShow(type);
 }
 
-function scEditEntry( cat, entry, newvalue, type ) {
-    if(entry.value() == newvalue) return;
-    entry.value( newvalue );
-    var req = new Request( 
-        SC_ENTRY_UPDATE.replace(/TYPE/, type), session, entry );
-    req.send(true);
-    var res = req.result();
-    if(checkILSEvent(res)) throw res;
-    scShow(type);
+function scEditEntry( cat, entry, row, type ) {
+    var newvalue = $n(row, 'sc_edit_entry_name').value;
+    var curvalue = entry.value();
+    var didupdate = false;
+
+    if( curvalue != newvalue ) {
+        entry.value( newvalue );
+        var req = new Request( 
+            SC_ENTRY_UPDATE.replace(/TYPE/, type), session, entry );
+        req.send(true);
+        var res = req.result();
+        if(checkILSEvent(res)) throw res;
+        didupdate = true;
+    }
+
+    if(type == ACTOR) {
+        didupdate = scEditEntryDefault( cat, entry, row );
+    }
+
+    if (didupdate) scShow(type);
 }
 
+function scEditEntryDefault( cat, entry, row ) {
+    var newsetdefault = $n(row, 'sc_edit_entry_default_set').checked;
+    var newownerdefault = getSelectorVal($n(row, 'sc_edit_entry_default_lib'));
+    var cursetdefault = false;
+    var curownerdefault = null;
+    var default_entry = null;
+
+    if( cat.default_entries && cat.default_entries()[0] && cat.default_entries()[0].stat_cat_entry() == entry.id() ) {
+        cursetdefault = true;
+        default_entry = cat.default_entries()[0];
+        curownerdefault = default_entry.owner();
+    }
+
+    if( cursetdefault == newsetdefault &&
+         (curownerdefault == newownerdefault || curownerdefault == null) ) {
+        return;
+    }
+
+    if( cursetdefault == true &&
+         newsetdefault == false ) {
+        var req = new Request( 
+            SC_ENTRY_DEFAULT_DELETE, session, default_entry.id() );
+        req.send(true);
+        var res = req.result();
+        if(checkILSEvent(res)) throw res;
+    }
+
+    if( newsetdefault == true ) {
+        var cat_id = cat.id();
+        var entry_id = entry.id();
+        default_entry = new actsced();
+        default_entry.isnew(1);
+        default_entry.stat_cat(cat_id);
+        default_entry.stat_cat_entry(entry_id);
+        default_entry.owner(newownerdefault);
+        var req = new Request( 
+            SC_ENTRY_DEFAULT_CREATE, session, default_entry );
+        req.send(true);
+        var res = req.result();
+        if(checkILSEvent(res)) throw res;
+    }
+
+    return true;
+}

commit dd20011fc24a1820ba80606e153e301986d15df2
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 16:10:00 2011 -0600

    Patron Stat Cat Enhancements: Add language entities for default stat cat entry labels.
    
    Add label entities for setting a default entry;  rename staff.server.admin.stat_cat.edit_entry_name_submit
    to staff.server.admin.stat_cat.edit_entry_submit.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd
index ea810c0..38b9866 100644
--- a/Open-ILS/web/opac/locale/en-US/lang.dtd
+++ b/Open-ILS/web/opac/locale/en-US/lang.dtd
@@ -2205,6 +2205,7 @@
 <!ENTITY staff.server.admin.stat_cat.usr_summary.label "Show in Summary">
 <!ENTITY staff.server.admin.stat_cat.entries.label "Entries">
 <!ENTITY staff.server.admin.stat_cat.add_entry "Add Entry">
+<!ENTITY staff.server.admin.stat_cat.set_default_entry "Default entry for">
 <!ENTITY staff.server.admin.stat_cat.edit "Edit">
 <!ENTITY staff.server.admin.stat_cat.none "(none)">
 <!ENTITY staff.server.admin.stat_cat.add.label "Add">
@@ -2215,7 +2216,7 @@
 <!ENTITY staff.server.admin.stat_cat.edit_delete "Delete Statistical Category">
 <!ENTITY staff.server.admin.stat_cat.cancel "Cancel">
 <!ENTITY staff.server.admin.stat_cat.edit_entry_owner "Owned By ">
-<!ENTITY staff.server.admin.stat_cat.edit_entry_name_submit "Update Entry Value">
+<!ENTITY staff.server.admin.stat_cat.edit_entry_submit "Update Entry Value">
 <!ENTITY staff.server.admin.stat_cat.edit_entry_delete "Delete Entry">
 <!ENTITY staff.server.admin.stat_cat.new_entry_name "Enter the value of the new entry: ">
 <!ENTITY staff.server.admin.stat_cat.new_entry_create "Create new entry">

commit 463d1af0d851db146f1b3d5da8ed3f1e14f9790c
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 16:06:19 2011 -0600

    Patron Stat Cat Enhancements: Add permissions for manipulating stat_cat_entry_default.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
index 01a2e3a..6c97858 100644
--- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql
+++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql
@@ -1537,7 +1537,13 @@ INSERT INTO permission.perm_list ( id, code, description ) VALUES
  ( 523, 'ADMIN_TOOLBAR', oils_i18n_gettext( 523,
     'Allows a user to create, edit, and delete custom toolbars', 'ppl', 'description' )),
  ( 524, 'PLACE_UNFILLABLE_HOLD', oils_i18n_gettext( 524,
-    'Allows a user to place a hold that cannot currently be filled.', 'ppl', 'description' ));
+    'Allows a user to place a hold that cannot currently be filled.', 'ppl', 'description' )),
+ ( 525, 'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT', oils_i18n_gettext( 525, 
+    'User may set a default entry in a patron statistical category', 'ppl', 'description' )),
+ ( 526, 'UPDATE_PATRON_STAT_CAT_ENTRY_DEFAULT', oils_i18n_gettext( 526, 
+    'User may reset a default entry in a patron statistical category', 'ppl', 'description' )),
+ ( 527, 'DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT', oils_i18n_gettext( 527, 
+    'User may unset a default entry in a patron statistical category', 'ppl', 'description' ));
 
 SELECT SETVAL('permission.perm_list_id_seq'::TEXT, 1000);
 
@@ -2058,12 +2064,14 @@ INSERT INTO permission.grp_perm_map (grp, perm, depth, grantable)
 			'CREATE_NON_CAT_TYPE',
 			'CREATE_PATRON_STAT_CAT',
 			'CREATE_PATRON_STAT_CAT_ENTRY',
+			'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT',
 			'CREATE_PATRON_STAT_CAT_ENTRY_MAP',
 			'CREATE_USER_GROUP_LINK',
 			'DELETE_BILLING_TYPE',
 			'DELETE_NON_CAT_TYPE',
 			'DELETE_PATRON_STAT_CAT',
 			'DELETE_PATRON_STAT_CAT_ENTRY',
+			'DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT',
 			'DELETE_PATRON_STAT_CAT_ENTRY_MAP',
 			'DELETE_TRANSIT',
 			'group_application.user.staff',

commit ac21f2eb4f45103acafa89513fb92e49a6efc5b4
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:56:25 2011 -0600

    Patron Stat Cat Enhancements: Add Publisher actor methods for stat_cat_entry_default objects.
    
    Add methods actor_stat_cat_entry_default and actor_stat_cat_entry_default_ancestor
    to retrieve and populate stat_cat_entry_default objects.  Modify ranged_actor_stat_cat_entry
    and fleshed_actor_stat_cat to also include default entry objects, if present.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/actor.pm
index c638e1c..d41dfcc 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/actor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/actor.pm
@@ -946,6 +946,7 @@ sub fleshed_actor_stat_cat {
 
 		my $sc_fm = $cat->to_fieldmapper;
 		$sc_fm->entries( [ map { $_->to_fieldmapper } $cat->entries ] );
+		$sc_fm->default_entries( [ map { $_->to_fieldmapper } $cat->default_entries ] );
 
 		$client->respond( $sc_fm );
 
@@ -995,6 +996,9 @@ sub ranged_actor_stat_cat_all {
 		$sc_fm->entries(
 			[ $self->method_lookup( 'open-ils.storage.ranged.actor.stat_cat_entry.search.stat_cat' )->run($ou,$sc->id) ]
 		) if ($fleshed);
+		$sc_fm->default_entries(
+			[ $self->method_lookup( 'open-ils.storage.actor.stat_cat_entry_default.ancestor.retrieve' )->run($ou,$sc->id) ]
+		) if ($fleshed);
 		$client->respond( $sc_fm );
 	}
 
@@ -1038,7 +1042,8 @@ sub ranged_actor_stat_cat_entry {
         $sth->execute($ou,$sc);
 
         for my $sce ( map { actor::stat_cat_entry->construct($_) } $sth->fetchall_hash ) {
-		$client->respond( $sce->to_fieldmapper );
+		my $sce_fm = $sce->to_fieldmapper;
+		$client->respond( $sce_fm );
 	}
 
         return undef;
@@ -1050,5 +1055,69 @@ __PACKAGE__->register_method(
         method          => 'ranged_actor_stat_cat_entry',
 );
 
+sub actor_stat_cat_entry_default {
+    my $self = shift;
+    my $client = shift;
+    my $ou = ''.shift();
+    my $sc = ''.shift();
+        
+    return undef unless ($ou);
+    my $s_table = actor::stat_cat_entry_default->table;
+
+    my $select = <<"    SQL";
+         SELECT  s.*
+         FROM  $s_table s
+         WHERE owner = ? AND stat_cat = ?
+    SQL
+
+    my $sth = actor::stat_cat->db_Main->prepare_cached($select);
+    $sth->execute($ou,$sc);
+
+    for my $sced ( map { actor::stat_cat_entry_default->construct($_) } $sth->fetchall_hash ) {
+        $client->respond( $sced->to_fieldmapper );
+    }
+
+    return undef;
+}
+__PACKAGE__->register_method(
+    api_name        => 'open-ils.storage.actor.stat_cat_entry_default.retrieve',
+    api_level       => 1,
+    stream          => 1,
+    method          => 'actor_stat_cat_entry_default',
+);
+
+sub actor_stat_cat_entry_default_ancestor {
+    my $self = shift;
+    my $client = shift;
+    my $ou = ''.shift();
+    my $sc = ''.shift();
+        
+    return undef unless ($ou);
+    my $s_table = actor::stat_cat_entry_default->table;
+
+    my $select = <<"    SQL";
+        SELECT  s.*
+        FROM  $s_table s
+        JOIN actor.org_unit_ancestors(?) p ON (p.id = s.owner)
+        WHERE stat_cat = ?
+    SQL
+
+    my $sth = actor::stat_cat->db_Main->prepare_cached($select);
+    $sth->execute($ou,$sc);
+
+    my @sced =  map { actor::stat_cat_entry_default->construct($_) } $sth->fetchall_hash;
+
+    my $ancestor_sced = pop @sced;
+
+    $client->respond( $ancestor_sced->to_fieldmapper ) if $ancestor_sced;
+
+    return undef;
+}
+__PACKAGE__->register_method(
+    api_name        => 'open-ils.storage.actor.stat_cat_entry_default.ancestor.retrieve',
+    api_level       => 1,
+    stream          => 1,
+    method          => 'actor_stat_cat_entry_default_ancestor',
+);
 
 1;

commit 234758498708a82c024f2af26720ebea5b77cd89
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:51:51 2011 -0600

    Patron Stat Cat Enhancements: Add Pg DBI actor::stat_cat_entry_default table and sequence.
    
    Add actor::stat_cat_entry_default->table and
    actor::stat_cat_entry_default->sequence.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/dbi.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/dbi.pm
index ae9bfda..47d3e8d 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/dbi.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/dbi.pm
@@ -519,6 +519,12 @@
 	actor::stat_cat_entry->sequence( 'actor.stat_cat_entry_id_seq' );
 	
 	#---------------------------------------------------------------------
+	package actor::stat_cat_entry_default;
+	
+	actor::stat_cat_entry_default->table( 'actor.stat_cat_entry_default' );
+	actor::stat_cat_entry_default->sequence( 'actor.stat_cat_entry_default_id_seq' );
+
+	#---------------------------------------------------------------------
 	package actor::stat_cat_entry_user_map;
 	
 	actor::stat_cat_entry_user_map->table( 'actor.stat_cat_entry_usr_map' );

commit f7522f2e0b631c92c9d1fb2efcaed4e54090a379
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:49:38 2011 -0600

    Patron Stat Cat Enhancements: Add CDBI package actor::stat_cat_entry_default.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm
index 4c2cbe9..d0e38b6 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm
@@ -129,6 +129,14 @@ __PACKAGE__->columns( Primary => qw/id/ );
 __PACKAGE__->columns( Essential => qw/stat_cat owner value/ );
 
 #-------------------------------------------------------------------------------
+package actor::stat_cat_entry_default;
+use base qw/actor/;
+
+__PACKAGE__->table( 'actor_stat_cat_entry_default' );
+__PACKAGE__->columns( Primary => qw/id/ );
+__PACKAGE__->columns( Essential => qw/stat_cat_entry stat_cat owner/ );
+
+#-------------------------------------------------------------------------------
 package actor::stat_cat_entry_user_map;
 use base qw/actor/;
 

commit 3be0d23c88cc5db64002cb2f7d877116d5c13242
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:46:34 2011 -0600

    Patron Stat Cat Enhancements: Link CDBI actor::stat_cat_entry_default to parent entities.
    
    Add relations between actor::stat_cat and actor::stat_cat_entry to actor::stat_cat_entry_default.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI.pm
index 1bf550d..56f20aa 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI.pm
@@ -484,8 +484,12 @@ sub modify_from_fieldmapper {
 	action::hold_request->has_many( transits => 'action::hold_transit_copy' );
 
 	actor::stat_cat_entry->has_a( stat_cat => 'actor::stat_cat' );
+	actor::stat_cat_entry->has_many( default_entries => 'actor::stat_cat_entry_default' );
+	actor::stat_cat_entry_default->has_a( stat_cat => 'actor::stat_cat' );
+	actor::stat_cat_entry_default->has_a( stat_cat_entry => 'actor::stat_cat_entry' );
 	actor::stat_cat->has_a( owner => 'actor::org_unit' );
 	actor::stat_cat->has_many( entries => 'actor::stat_cat_entry' );
+	actor::stat_cat->has_many( default_entries => 'actor::stat_cat_entry_default' );
 	actor::stat_cat_entry_user_map->has_a( stat_cat => 'actor::stat_cat' );
 	actor::stat_cat_entry_user_map->has_a( stat_cat_entry => 'actor::stat_cat_entry' );
 	actor::stat_cat_entry_user_map->has_a( target_usr => 'actor::user' );

commit 75bdd9b0d70ff7010106210ec2349041e41a08cd
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:42:44 2011 -0600

    Patron Stat Cat Enhancements: Add OpenSRF CRUD methods for actor statistical category default entries.
    
    Added methods to create, delete, update default entries for patron statistical
    categories.  Modified create_stat_cat and create_stat_cat_entry to also create,
    update stat_cat_entry_default objects if present in the request.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/StatCat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/StatCat.pm
index d0a843e..cf52a34 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/StatCat.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/StatCat.pm
@@ -154,8 +154,10 @@ sub stat_cat_create {
 
 	my $method = "open-ils.storage.direct.actor.stat_cat.create";
 	my $entry_create = "open-ils.storage.direct.actor.stat_cat_entry.create";
+	my $default_entry_create = "open-ils.storage.direct.actor.stat_cat_entry_default.create";
 	my $perm = 'CREATE_PATRON_STAT_CAT';
 	my $eperm = 'CREATE_PATRON_STAT_CAT_ENTRY';
+	my $edperm = 'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT';
 
 	if($self->api_name =~ /asset/) {
 		$method = "open-ils.storage.direct.asset.stat_cat.create";
@@ -183,7 +185,16 @@ sub stat_cat_create {
 	if( ref($stat_cat->entries) ) {
 		for my $entry (@{$stat_cat->entries}) {
 			$entry->stat_cat($newid);
-			_create_stat_entry($session, $entry, $entry_create);
+			my $entry_id = _create_stat_entry($session, $entry, $entry_create);
+			if( $self->api_name =~ /actor/ && ref($entry->default_entries) ) {
+				$evt = $apputils->check_perms($user_obj->id, $stat_cat->owner, $edperm);
+				return $evt if $evt;
+
+				for my $default_entry (@{$entry->default_entries}) {
+					$default_entry->stat_cat_entry($entry_id);
+					_create_stat_entry_default($session, $default_entry, $default_entry_create);
+				}
+			}
 		}
 	}
 
@@ -305,6 +316,25 @@ sub update_stat_entry {
 	return 1;
 }
 
+sub _update_stat_entry_default {
+    my( $session, $default_entry, $method) = @_;
+
+    warn "Updating new default stat entry for stat_cat " . $default_entry->stat_cat . 
+        " for org unit " . $default_entry->owner .
+        " with new entry id " . $default_entry->stat_cat_entry . "\n";
+
+    my $req = $session->request($method, $default_entry);
+    my $status = $req->gather(1);
+
+    warn "Default stat entry " . Dumper($default_entry) . "\n";	
+	
+    if(!$status) {
+        throw OpenSRF::EX::ERROR 
+        ("Error updating default stat cat entry"); }
+
+    warn "Default stat cat entry update returned status $status\n";
+    return $status;
+}
 
 __PACKAGE__->register_method(
 	method	=> "update_stat",
@@ -351,10 +381,16 @@ sub create_stat_entry {
 	my( $self, $client, $user_session, $entry ) = @_;
 
 	my $method = "open-ils.storage.direct.actor.stat_cat_entry.create";
+	my $default_entry_create = "open-ils.storage.direct.actor.stat_cat_entry_default.create";
+	my $default_entry_update = "open-ils.storage.direct.actor.stat_cat_entry_default.update";
 	my $perm = 'CREATE_PATRON_STAT_CAT_ENTRY';
+	my $edperm = 'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT';
+	my $edperm_update = 'UPDATE_PATRON_STAT_CAT_ENTRY_DEFAULT';
+	my $type = 'actor';
 	if($self->api_name =~ /asset/) {
 		$method = "open-ils.storage.direct.asset.stat_cat_entry.create";
 		$perm = 'CREATE_COPY_STAT_CAT_ENTRY';
+		$type = 'asset';
 	}
 
 	my( $user_obj, $evt )  = $apputils->checkses($user_session); 
@@ -362,18 +398,99 @@ sub create_stat_entry {
 	$evt = $apputils->check_perms( $user_obj->id, $entry->owner, $perm );
 	return $evt if $evt;
 
-	$entry->clear_id();
 	my $session = $apputils->start_db_session();
 	$apputils->set_audit_info($session, $user_session, $user_obj->id, $user_obj->wsid);
-	my $req = $session->request($method, $entry); 
-	my $status = $req->gather(1);
+	my $newid = _create_stat_entry($session, $entry, $method);
+
+	if( $self->api_name =~ /actor/ && ref($entry->default_entries) ) {
+		$evt = $apputils->check_perms($user_obj->id, $entry->owner, $edperm);
+		return $evt if $evt;
+
+		for my $default_entry (@{$entry->default_entries}) {
+			$default_entry->stat_cat_entry($newid);
+			my $target;
+			($target, $evt) = $apputils->fetch_stat_cat_entry_default_by_stat_cat_and_org($type, 
+													$default_entry->stat_cat, 
+													$default_entry->owner);
+			if( $target ) {
+				$evt = $apputils->check_perms($user_obj->id, $default_entry->owner, $edperm_update);
+				return $evt if $evt;
+				$target->stat_cat_entry($newid);
+				_update_stat_entry_default($session, $target, $default_entry_update);
+			} else {
+				_create_stat_entry_default($session, $default_entry, $default_entry_create);
+			}
+		}
+	}
+
 	$apputils->commit_db_session($session);
 
-	$logger->info("created stat cat entry $status");
-	return $status;
+	$logger->info("created stat cat entry $newid");
+
+	return $newid;
 }
 
+__PACKAGE__->register_method(
+    method => "create_stat_entry_default",
+    api_name => "open-ils.circ.stat_cat.actor.entry.default.create");
+
+
+sub create_stat_entry_default {
+    my( $self, $client, $user_session, $default_entry ) = @_;
+
+    my $create_method = "open-ils.storage.direct.actor.stat_cat_entry_default.create";
+    my $update_method = "open-ils.storage.direct.actor.stat_cat_entry_default.update";
+    my $create_perm = 'UPDATE_PATRON_STAT_CAT_ENTRY_DEFAULT';
+    my $update_perm = 'CREATE_PATRON_STAT_CAT_ENTRY_DEFAULT';
+    my $type = 'actor';
+    my ($target, $id);
+
+    my( $user_obj, $evt )  = $apputils->checkses($user_session); 
+    return $evt if $evt;
+
+    my $session = $apputils->start_db_session();
+
+    ($target, $evt) = $apputils->fetch_stat_cat_entry_default_by_stat_cat_and_org(
+        $type, 
+        $default_entry->stat_cat, 
+        $default_entry->owner);
+    if( $target ) {
+        $evt = $apputils->check_perms($user_obj->id, $default_entry->owner, $update_perm);
+        return $evt if $evt;
+        $id = $target->id;
+        $default_entry->id($id);
+        _update_stat_entry_default($session, $default_entry, $update_method);
+        $logger->info("updated stat cat default entry $id");
+    } else {
+        $evt = $apputils->check_perms($user_obj->id, $default_entry->owner, $create_perm);
+        return $evt if $evt;
+        $id = _create_stat_entry_default($session, $default_entry, $create_method);
+        $logger->info("created stat cat default entry $id");
+    }
+
+    $apputils->commit_db_session($session);
+
+    return $id;
+}
+
+sub _create_stat_entry_default {
+    my( $session, $stat_entry_default, $method) = @_;
+
+    warn "Creating new default stat entry for stat_cat " . $stat_entry_default->stat_cat . "\n";
+    $stat_entry_default->clear_id();
+
+    my $req = $session->request($method, $stat_entry_default);
+    my $id = $req->gather(1);
 
+    warn "Default stat entry " . Dumper($stat_entry_default) . "\n";	
+
+    if(!$id) {
+        throw OpenSRF::EX::ERROR 
+        ("Error creating new default stat cat entry"); }
+
+    warn "Default stat cat entry create returned id $id\n";
+    return $id;
+}
 
 __PACKAGE__->register_method(
 	method	=> "create_stat_map",
@@ -599,6 +716,41 @@ sub _delete_entry {
 
 
 __PACKAGE__->register_method(
+    method => "delete_entry_default",
+    api_name => "open-ils.circ.stat_cat.actor.entry.default.delete");
+
+sub delete_entry_default {
+    my( $self, $client, $user_session, $target ) = @_;
+
+    my $type = "actor";
+    my $perm = 'DELETE_PATRON_STAT_CAT_ENTRY_DEFAULT';
+
+    my $default_entry;
+    my( $user_obj, $evt )  = $apputils->checkses($user_session); 
+    return $evt if $evt;
+
+    ( $default_entry, $evt ) = $apputils->fetch_stat_cat_entry_default( $type, $target );
+    return $evt if $evt;
+
+    $evt = $apputils->check_perms( $user_obj->id, $default_entry->owner, $perm );
+    return $evt if $evt;
+
+    my $session = OpenSRF::AppSession->create("open-ils.storage");
+    return _delete_entry_default($session, $target, $type);
+}
+
+sub _delete_entry_default {
+    my( $session, $stat_entry, $type) = @_;
+
+    my $method = "open-ils.storage.direct.actor.stat_cat_entry_default.delete";
+    if($type =~ /asset/ ) {
+        $method = "open-ils.storage.direct.asset.stat_cat_entry_default.delete";
+    }
+
+    return $session->request($method, $stat_entry)->gather(1);
+}
+
+__PACKAGE__->register_method(
 	method => 'fetch_stats_by_copy',
 	api_name	=> 'open-ils.circ.asset.stat_cat_entries.fleshed.retrieve_by_copy',
 );
@@ -635,6 +787,19 @@ sub fetch_stats_by_copy {
 	return \@entries;
 }
 
+__PACKAGE__->register_method(
+    method => 'retrieve_entry_default',
+    api_name => "open-ils.circ.stat_cat.actor.entry_default.ancestor_default",
+);
+
+sub retrieve_entry_default {
+    my( $self, $client, $user_session, $orgid, $stat_cat ) = @_;
+	
+    my $method = "open-ils.storage.actor.stat_cat_entry_default.ancestor.retrieve.atomic";
+
+    return $apputils->simple_scalar_request( "open-ils.storage", $method, $orgid, $stat_cat);
+}
+
 
 
 1;

commit 53ab5197ecf61923e28f69c58d79cc4c56196e21
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:36:15 2011 -0600

    Patron Stat Cat Enhancements: Add OpenSRF methods for retrieving actor stat cat default entries.
    
    Added the methods 'fetch_stat_cat_entry_default' and
    'fetch_stat_cat_entry_default_by_stat_cat_and_org' for
    fetching stat_cat_entry_default objects.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm
index 2bc09cf..792f53b 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AppUtils.pm
@@ -790,6 +790,37 @@ sub fetch_stat_cat_entry {
 	return ( $entry, $evt );
 }
 
+sub fetch_stat_cat_entry_default {
+    my( $self, $type, $id ) = @_;
+    my( $entry_default, $evt );
+    $logger->debug("Fetching $type stat cat entry default: $id");
+    $entry_default = $self->simplereq(
+        'open-ils.cstore', 
+        "open-ils.cstore.direct.$type.stat_cat_entry_default.retrieve", $id );
+
+    my $e = 'ASSET_STAT_CAT_ENTRY_DEFAULT_NOT_FOUND';
+    $e = 'ACTOR_STAT_CAT_ENTRY_DEFAULT_NOT_FOUND' if $type eq 'actor';
+
+    $evt = OpenILS::Event->new( $e, id => $id ) unless $entry_default;
+    return ( $entry_default, $evt );
+}
+
+sub fetch_stat_cat_entry_default_by_stat_cat_and_org {
+    my( $self, $type, $stat_cat, $orgId ) = @_;
+    my $entry_default;
+    $logger->info("### Fetching $type stat cat entry default with stat_cat $stat_cat owned by org_unit $orgId");
+    $entry_default = $self->simplereq(
+        'open-ils.cstore', 
+        "open-ils.cstore.direct.$type.stat_cat_entry_default.search.atomic", 
+        { stat_cat => $stat_cat, owner => $orgId } );
+
+    $entry_default = $entry_default->[0];
+    return ($entry_default, undef) if $entry_default;
+
+    my $e = 'ASSET_STAT_CAT_ENTRY_DEFAULT_NOT_FOUND';
+    $e = 'ACTOR_STAT_CAT_ENTRY_DEFAULT_NOT_FOUND' if $type eq 'actor';
+    return (undef, OpenILS::Event->new($e) );
+}
 
 sub find_org {
 	my( $self, $org_tree, $orgid )  = @_;

commit 5c86f181a70433399a30f85a1be3a4da145d60a6
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:31:58 2011 -0600

    Patron Stat Cat Enhancements: Add event for ACTOR_STAT_CAT_ENTRY_DEFAULT_NOT_FOUND
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/extras/ils_events.xml b/Open-ILS/src/extras/ils_events.xml
index 2eeffb7..458dd49 100644
--- a/Open-ILS/src/extras/ils_events.xml
+++ b/Open-ILS/src/extras/ils_events.xml
@@ -478,8 +478,9 @@
 	<event code='1610' textcode='MONEY_CHECK_PAYMENT_NOT_FOUND'>
 		<desc xml:lang='en-US'>The requested money_check_payment was not found</desc>
 	</event>
-
-
+	<event code='1611' textcode='ACTOR_STAT_CAT_ENTRY_DEFAULT_NOT_FOUND'>
+		<desc xml:lang='en-US'>The requested actor_stat_cat_entry_default was not found</desc>
+	</event>
 	<event code='1612' textcode='CONFIG_RULES_MAX_FINE_NOT_FOUND'>
 		<desc xml:lang='en-US'>The requested config_rules_max_fine was not found</desc>
 	</event>

commit f894f96cc00d99d7a164be748d85f661d9e24b97
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Dec 27 15:28:00 2011 -0600

    Patron Stat Cat Enhancements: Add stat_cat_entry_default IDL class
    
    Add stat_cat_entry_default IDL class, and links to actor.stat_cat and
    actor.stat_cat_entry
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index 05119ae..c9357ba 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -5058,6 +5058,7 @@ SELECT  usr,
 	<class id="actsc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="actor::stat_cat" oils_persist:tablename="actor.stat_cat" reporter:label="User Statistical Category">
 		<fields oils_persist:primary="id" oils_persist:sequence="actor.stat_cat_id_seq">
 			<field reporter:label="Entries" name="entries" oils_persist:virtual="true" reporter:datatype="link"/>
+			<field reporter:label="Default Entries" name="default_entries" oils_persist:virtual="true" reporter:datatype="link"/>
 			<field reporter:label="Stat Cat ID" name="id" reporter:datatype="id" reporter:selector="name"/>
 			<field reporter:label="Name" name="name" reporter:datatype="text" oils_persist:i18n="true"/>
 			<field reporter:label="OPAC Visible" name="opac_visible" reporter:datatype="bool"/>
@@ -5073,6 +5074,7 @@ SELECT  usr,
 			<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
 			<link field="sip_field" reltype="has_a" key="field" map="" class="actscsf"/>
 			<link field="entries" reltype="has_many" key="stat_cat" map="" class="actsce"/>
+			<link field="default_entries" reltype="has_many" key="stat_cat" map="" class="actsced"/>
 		</links>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
             <actions>
@@ -5293,10 +5295,25 @@ SELECT  usr,
 			<field reporter:label="Entry Owner" name="owner" reporter:datatype="link"/>
 			<field reporter:label="Stat Cat" name="stat_cat" reporter:datatype="link"/>
 			<field reporter:label="Entry Value" name="value" reporter:datatype="text"/>
+			<field reporter:label="Default Entries" name="default_entries" oils_persist:virtual="true" reporter:datatype="link"/>
 		</fields>
 		<links>
 			<link field="stat_cat" reltype="has_a" key="id" map="" class="actsc"/>
 			<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+			<link field="default_entries" reltype="has_many" key="stat_cat_entry" map="" class="actsced"/>
+		</links>
+	</class>
+	<class id="actsced" controller="open-ils.cstore" oils_obj:fieldmapper="actor::stat_cat_entry_default" oils_persist:tablename="actor.stat_cat_entry_default" reporter:label="User Stat Cat Default Entry">
+		<fields oils_persist:primary="id" oils_persist:sequence="actor.stat_cat_entry_default_id_seq">
+			<field reporter:label="Default Entry ID" name="id" reporter:datatype="id" />
+			<field reporter:label="Default Entry Value" name="stat_cat_entry" reporter:datatype="link"/>
+			<field reporter:label="Stat Cat" name="stat_cat" reporter:datatype="link"/>
+			<field reporter:label="Default for Owner" name="owner" reporter:datatype="link"/>
+		</fields>
+		<links>
+			<link field="stat_cat" reltype="has_a" key="id" map="" class="actsc"/>
+			<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
+			<link field="stat_cat_entry" reltype="has_a" key="id" map="" class="actsce"/>
 		</links>
 	</class>
 	<class id="cubi" controller="open-ils.cstore" oils_obj:fieldmapper="container::user_bucket_item" oils_persist:tablename="container.user_bucket_item" reporter:label="User Bucket Item">

commit fa24df6e6d59cc052ca9ea38caaaa19a0096654d
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Mar 20 22:14:07 2012 -0500

    Patron Stat Cat Enhancements: Add default entry table to database
    
    Add actor.stat_cat_entry_default table to Pg database.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/src/sql/Pg/005.schema.actors.sql b/Open-ILS/src/sql/Pg/005.schema.actors.sql
index a6edeb9..4f9f39b 100644
--- a/Open-ILS/src/sql/Pg/005.schema.actors.sql
+++ b/Open-ILS/src/sql/Pg/005.schema.actors.sql
@@ -188,6 +188,8 @@ CREATE TABLE actor.stat_cat (
     sip_field   CHAR(2) REFERENCES actor.stat_cat_sip_fields(field) ON UPDATE CASCADE ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
     sip_format  TEXT,
     checkout_archive    BOOL NOT NULL DEFAULT FALSE,
+	required	BOOL NOT NULL DEFAULT FALSE,
+	allow_freetext	BOOL NOT NULL DEFAULT TRUE,
 	CONSTRAINT sc_once_per_owner UNIQUE (owner,name)
 );
 COMMENT ON TABLE actor.stat_cat IS $$
@@ -363,6 +365,21 @@ CREATE TABLE actor.org_unit_proximity (
 );
 CREATE INDEX from_prox_idx ON actor.org_unit_proximity (from_org);
 
+CREATE TABLE actor.stat_cat_entry_default (
+	id		SERIAL	PRIMARY KEY,
+        stat_cat_entry	INT	NOT NULL REFERENCES actor.stat_cat_entry(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+	stat_cat	INT	NOT NULL REFERENCES actor.stat_cat(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+	owner		INT	NOT NULL REFERENCES actor.org_unit(id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+	CONSTRAINT sced_once_per_owner UNIQUE (stat_cat,owner)
+);
+COMMENT ON TABLE actor.stat_cat_entry_default IS $$
+User Statistical Category Default Entry
+
+A library may choose one of the stat_cat entries to be the
+default entry.
+$$;
+
+
 CREATE TABLE actor.hours_of_operation (
 	id		INT	PRIMARY KEY REFERENCES actor.org_unit (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
 	dow_0_open	TIME	NOT NULL DEFAULT '09:00',

commit a489e2d4d26938be04e7a56e382967252b03e652
Author: Scott Prater <sprater at gmail.com>
Date:   Tue Mar 20 22:12:21 2012 -0500

    Patron Stat Cat Enhancements: Add 'allow free text' and 'required' flags
    
    Add database entities, controller mappings, and HTML/Javascript
    widgets to allow administrators to set and persist 'required'
    and 'allow free text' boolean flags for patron statistical categories
    in the Statistical Categories Editor.
    
    Signed-off-by: Scott Prater <sprater at gmail.com>
    Signed-off-by: Ben Shum <bshum at biblio.org>
    Signed-off-by: Thomas Berezansky <tsbere at mvlc.org>

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index fe0af0d..05119ae 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -5066,6 +5066,8 @@ SELECT  usr,
 			<field reporter:label="SIP Field" name="sip_field" reporter:datatype="link"/>
 			<field reporter:label="SIP Format" name="sip_format" reporter:datatype="text"/>
 			<field reporter:label="Checkout Archive" name="checkout_archive" reporter:datatype="bool"/>
+			<field reporter:label="Required" name="required" reporter:datatype="bool"/>
+			<field reporter:label="Free Text" name="allow_freetext" reporter:datatype="bool"/>
 		</fields>
 		<links>
 			<link field="owner" reltype="has_a" key="id" map="" class="aou"/>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm
index d95baa1..4c2cbe9 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/CDBI/actor.pm
@@ -118,7 +118,7 @@ use base qw/actor/;
 
 __PACKAGE__->table( 'actor_stat_cat' );
 __PACKAGE__->columns( Primary => qw/id/ );
-__PACKAGE__->columns( Essential => qw/owner name opac_visible usr_summary sip_field sip_format checkout_archive/ );
+__PACKAGE__->columns( Essential => qw/owner name opac_visible usr_summary sip_field sip_format checkout_archive required allow_freetext/ );
 
 #-------------------------------------------------------------------------------
 package actor::stat_cat_entry;
diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd
index 29e809c..ea810c0 100644
--- a/Open-ILS/web/opac/locale/en-US/lang.dtd
+++ b/Open-ILS/web/opac/locale/en-US/lang.dtd
@@ -2183,6 +2183,7 @@
 <!ENTITY staff.server.admin.stat_cat.owning_library "Owning Library: ">
 <!ENTITY staff.server.admin.stat_cat.opac_visibility "OPAC Visibility: ">
 <!ENTITY staff.server.admin.stat_cat.required "Required: ">
+<!ENTITY staff.server.admin.stat_cat.allow_freetext "Allow Free Text: ">
 <!ENTITY staff.server.admin.stat_cat.usr_summary "Show in Summary: ">
 <!ENTITY staff.server.admin.stat_cat.on "On">
 <!ENTITY staff.server.admin.stat_cat.off "Off">
@@ -2200,6 +2201,7 @@
 <!ENTITY staff.server.admin.stat_cat.owning_library.label "Owning Library">
 <!ENTITY staff.server.admin.stat_cat.opac_visibility.label "OPAC Visibility">
 <!ENTITY staff.server.admin.stat_cat.required.label "Required">
+<!ENTITY staff.server.admin.stat_cat.allow_freetext.label "Allow Free Text">
 <!ENTITY staff.server.admin.stat_cat.usr_summary.label "Show in Summary">
 <!ENTITY staff.server.admin.stat_cat.entries.label "Entries">
 <!ENTITY staff.server.admin.stat_cat.add_entry "Add Entry">
diff --git a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js
index 8edabfd..eee8022 100644
--- a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js
+++ b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.js
@@ -164,10 +164,10 @@ function scDraw( type, cats ) {
 
     if(type == ACTOR) {
         unHideMe($('sc_usr_summary_label'));
-        hideMe($('sc_required_label'));
+        unHideMe($('sc_usr_freetext_label'));
     } else {
-        unHideMe($('sc_required_label'));
         hideMe($('sc_usr_summary_label'));
+        hideMe($('sc_usr_freetext_label'));
     }
 
     scCounter = 0;
@@ -180,6 +180,7 @@ function scInsertCat( tbody, cat, type ) {
 
     var row = scRow.cloneNode(true);
     row.id = 'sc_tr_' + cat.id();
+    var required = cat.required();
     var name_td = $n(row, 'sc_name');
     name_td.appendChild( text(cat.name()) );
     if(scCounter++ % 2) addCSSClass(row, 'has_color');
@@ -207,20 +208,24 @@ function scInsertCat( tbody, cat, type ) {
     else
         unHideMe($n(row, 'sc_checkout_archive'));
 
+    if(isTrue(required))
+        unHideMe($n(row, 'sc_required_on'));
+    else 
+        unHideMe($n(row, 'sc_required'));
+
     if(type == ACTOR) {
         if(isTrue(cat.usr_summary()))
             unHideMe($n(row, 'sc_usr_summary_on'));
         else 
             unHideMe($n(row, 'sc_usr_summary'));
 
-        hideMe($n(row, 'sc_required_td'));
-    } else {
-        if(isTrue(cat.required()))
-            unHideMe($n(row, 'sc_required_on'));
+        if(isTrue(cat.allow_freetext()))
+            unHideMe($n(row, 'sc_usr_freetext_on'));
         else 
-            unHideMe($n(row, 'sc_required'));
-
+            unHideMe($n(row, 'sc_usr_freetext'));
+    } else {
         hideMe($n(row, 'sc_usr_summary_td'));
+        hideMe($n(row, 'sc_usr_freetext_td'));
     }
 
     tbody.appendChild(row);
@@ -317,18 +322,18 @@ function scBuildNew() {
     var type = getSelectorVal(typeSel);
     switch(type) {
         case ACTOR:
-            hideMe($('required_td1'));
-            hideMe($('required_td2'));
             unHideMe($('usr_summary_td1'));
             unHideMe($('usr_summary_td2'));
             unHideMe($('sip_tr'));
+            unHideMe($('usr_freetext_td1'));
+            unHideMe($('usr_freetext_td2'));
         break;
         case ASSET:
             hideMe($('usr_summary_td1'));
             hideMe($('usr_summary_td2'));
             hideMe($('sip_tr'));
-            unHideMe($('required_td1'));
-            unHideMe($('required_td2'));
+            hideMe($('usr_freetext_td1'));
+            hideMe($('usr_freetext_td2'));
         break;
     }
     var org_list = PERMS[type].create_stat_cat;
@@ -355,19 +360,21 @@ function scNew() {
     var required = 0;
     var usr_summary = 0;
     var checkout_archive = 0;
+    var usr_freetext = 0;
     if( $('sc_make_opac_visible').checked) visible = 1;
     if( $('sc_make_required').checked) required = 1;
     if( $('sc_make_usr_summary').checked) usr_summary = 1;
     if( $('sc_make_checkout_archive').checked) checkout_archive = 1;
+    if( $('sc_make_usr_freetext').checked) usr_freetext = 1;
 
     var cat;
     if( type == ACTOR ) {
         cat = new actsc();
         cat.usr_summary( usr_summary );
+        cat.allow_freetext( usr_freetext );
     }
     if( type == ASSET ) {
         cat = new asc();
-        cat.required( required );
     }
     var field = getSelectorVal($('sc_sip_field'));
     if(field.length == 2) cat.sip_field(field);
@@ -375,6 +382,7 @@ function scNew() {
     cat.sip_format($('sc_sip_format').value);
 
     cat.opac_visible(visible);
+    cat.required( required );
     cat.name(name);
     cat.checkout_archive(checkout_archive);
     cat.owner(getSelectorVal($('sc_owning_lib_selector')));
@@ -400,21 +408,25 @@ function scEdit( tbody, type, cat ) {
     if(r.nextSibling) { tbody.insertBefore( row, r.nextSibling ); }
     else{ tbody.appendChild(row); }
 
+    var required = cat.required();
+    var reqcb = $n(row, 'sc_edit_required');
+    reqcb.checked = isTrue(required); 
+
     scPopSipFields($n(row, 'sc_edit_sip_field'), type);
     $n(row, 'sc_edit_name').value = cat.name();
     setSelector($n(row, 'sc_edit_sip_field'), cat.sip_field());
     $n(row, 'sc_edit_sip_format').value = cat.sip_format();
 
     if(type == ACTOR) {
-        var cb = $n(row, 'sc_edit_usr_summary');
-        cb.checked = isTrue(cat.usr_summary()); 
-        hideMe($n(row, 'sc_edit_required_td'));
+        var cb1 = $n(row, 'sc_edit_usr_summary');
+        var cb2 = $n(row, 'sc_edit_usr_freetext');
+        cb1.checked = isTrue(cat.usr_summary()); 
+        cb2.checked = isTrue(cat.allow_freetext()); 
         unHideMe($n(row, 'sc_edit_usr_summary_td'));
+        unHideMe($n(row, 'sc_edit_usr_freetext_td'));
     } else {
-        var cb = $n(row, 'sc_edit_required');
-        cb.checked = isTrue(cat.required()); 
         hideMe($n(row, 'sc_edit_usr_summary_td'));
-        unHideMe($n(row, 'sc_edit_required_td'));
+        hideMe($n(row, 'sc_edit_usr_freetext_td'));
     }
 
     var name = $n(row, 'sc_edit_cancel');
@@ -439,12 +451,9 @@ function scEdit( tbody, type, cat ) {
     name.select();
 
     if( cat.opac_visible() != 0 && cat.opac_visible() != '0' ) {
-        $n( $n(row, 'sc_edit_opac_vis'), 
-            'sc_edit_opac_visibility').checked = true;
-    } else {
-        $n( $n(row, 'sc_edit_opac_invis'), 
+        $n( $n(row, 'sc_edit_opac_visibility'), 
             'sc_edit_opac_visibility').checked = true;
-    }
+    } 
 
     $n( row, 'sc_edit_checkout_archive' ).checked = isTrue(cat.checkout_archive());
 
@@ -467,33 +476,31 @@ function scEdit( tbody, type, cat ) {
 function scEditGo( type, cat, row, selector ) {
     var name = $n(row, 'sc_edit_name').value;
     var visible = 
-        $n( $n(row, 'sc_edit_opac_vis'), 'sc_edit_opac_visibility').checked;
+        $n( $n(row, 'sc_edit_opac_visibility'), 'sc_edit_opac_visibility').checked;
 
     var newlib = cat.owner();
     if(selector) newlib = getSelectorVal( selector );
 
     if(!name) return false;
 
-    var usr_summary = $n(row, 'sc_edit_usr_summary').checked;
     var required = $n(row, 'sc_edit_required').checked;
+    var usr_summary = $n(row, 'sc_edit_usr_summary').checked;
     var sip_field = getSelectorVal( $n(row, 'sc_edit_sip_field') );
+    var usr_freetext = $n(row, 'sc_edit_usr_freetext').checked;
 
     cat.name( name );
     cat.owner( newlib );
     cat.entries(null);
     cat.opac_visible(0);
     cat.checkout_archive($n(row, 'sc_edit_checkout_archive').checked ? 1 : 0);
+    cat.required( (required) ? 1 : 0 );
     if(sip_field.length == 2) cat.sip_field( sip_field );
     else cat.sip_field(null);
     cat.sip_format($n(row, 'sc_edit_sip_format').value);
     if( visible ) cat.opac_visible(1);
-    switch(type) {
-        case ACTOR:
-            cat.usr_summary( (usr_summary) ? 1 : 0 );
-        break;
-        case ASSET:
-            cat.required( (required) ? 1 : 0 );
-        break;
+    if(type == ACTOR) {
+        cat.usr_summary( (usr_summary) ? 1 : 0 );
+        cat.allow_freetext( (usr_freetext) ? 1 : 0 );
     }
 
     var req = new Request( SC_UPDATE.replace(/TYPE/,type), session, cat );
diff --git a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
index 0e98cba..f644cae 100644
--- a/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
+++ b/Open-ILS/xul/staff_client/server/admin/stat_cat_editor.xhtml
@@ -104,6 +104,15 @@
                         </td>
                     </tr>
                     <tr>
+                        <td id='usr_freetext_td1'>&staff.server.admin.stat_cat.allow_freetext;</td>
+                        <td id='usr_freetext_td2'>    
+                            <span>&staff.server.admin.stat_cat.on;</span>
+                            <input type='radio' name='usr_freetext' id='sc_make_usr_freetext' checked='checked'> </input>
+                            <span>&staff.server.admin.stat_cat.off;</span>
+                            <input type='radio' name='usr_freetext'> </input>
+                        </td>
+                    </tr>
+                    <tr>
                         <td>&staff.server.admin.stat_cat.sip_field;</td>
                         <td>
                             <select name='sip_field' id='sc_sip_field'>
@@ -163,6 +172,7 @@
                             <td>&staff.server.admin.stat_cat.opac_visibility.label;</td>
                             <td id='sc_required_label'>&staff.server.admin.stat_cat.required.label;</td>
                             <td id='sc_usr_summary_label'>&staff.server.admin.stat_cat.usr_summary.label;</td>
+                            <td id='sc_usr_freetext_label'>&staff.server.admin.stat_cat.allow_freetext.label;</td>
                             <td>&staff.server.admin.stat_cat.sip_field.label;</td>
                             <td>&staff.server.admin.stat_cat.sip_format.label;</td>
                             <td>&staff.server.admin.stat_cat.checkout_archive.label;</td>
@@ -176,7 +186,6 @@
                         <tr id='sc_tr'>
                             <td><b name='sc_name'> </b></td>
                             <td name='sc_owning_lib'> </td>
-    
                             <td>
                                 <span class='hide_me' name='sc_opac_visible'>&staff.server.admin.stat_cat.on;</span> 
                                 <span class='hide_me' name='sc_opac_invisible'>&staff.server.admin.stat_cat.off;</span> 
@@ -189,6 +198,10 @@
                                 <span class='hide_me' name='sc_usr_summary_on'>&staff.server.admin.stat_cat.on;</span> 
                                 <span class='hide_me' name='sc_usr_summary'>&staff.server.admin.stat_cat.off;</span> 
                             </td>
+                            <td name='sc_usr_freetext_td'>
+                                <span class='hide_me' name='sc_usr_freetext_on'>&staff.server.admin.stat_cat.on;</span> 
+                                <span class='hide_me' name='sc_usr_freetext'>&staff.server.admin.stat_cat.off;</span> 
+                            </td>
                             <td>
                                 <span class='hide_me' name='sc_sip_field_none'>&staff.server.admin.stat_cat.sip_field.none.label;</span>
                                 <span class='hide_me' name='sc_sip_field_value' ></span>
@@ -236,16 +249,8 @@
                     <span class='hide_me' name='sc_edit_show_owning_lib'> </span>
                     <select class='hide_me' name='sc_edit_owning_lib'> </select>
                 </td>
-
-                <td>
-                    <span>&staff.server.admin.stat_cat.on;</span>
-                    <span name='sc_edit_opac_vis'>
-                        <input type='radio' name='sc_edit_opac_visibility'> </input>
-                    </span>
-                    <span>&staff.server.admin.stat_cat.off;</span>
-                    <span name='sc_edit_opac_invis'>
-                        <input type='radio' name='sc_edit_opac_visibility'> </input>
-                    </span>
+                <td name='sc_edit_opac_visibility_td'>
+                    <input type='checkbox' name='sc_edit_opac_visibility'/>
                 </td>
                 <td name='sc_edit_required_td'>
                     <input type='checkbox' name='sc_edit_required'/>
@@ -253,6 +258,9 @@
                 <td name='sc_edit_usr_summary_td'>
                     <input type='checkbox' name='sc_edit_usr_summary'/>
                 </td>
+                <td name='sc_edit_usr_freetext_td'>
+                    <input type='checkbox' name='sc_edit_usr_freetext'/>
+                </td>
                 <td>
                     <select name='sc_edit_sip_field'>
                         <option value=''>&staff.server.admin.stat_cat.sip_field.none;</option>

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/examples/fm_IDL.xml                       |   19 ++
 Open-ILS/src/extras/ils_events.xml                 |    5 +-
 .../perlmods/lib/OpenILS/Application/AppUtils.pm   |   31 +++
 .../lib/OpenILS/Application/Circ/StatCat.pm        |  177 +++++++++++++++-
 .../lib/OpenILS/Application/Storage/CDBI.pm        |    4 +
 .../lib/OpenILS/Application/Storage/CDBI/actor.pm  |   10 +-
 .../OpenILS/Application/Storage/Driver/Pg/dbi.pm   |    6 +
 .../OpenILS/Application/Storage/Publisher/actor.pm |   71 ++++++-
 Open-ILS/src/sql/Pg/002.schema.config.sql          |    2 +-
 Open-ILS/src/sql/Pg/005.schema.actors.sql          |   17 ++
 Open-ILS/src/sql/Pg/950.data.seed-values.sql       |   10 +-
 ...01.schema.patron_stat_category_enhancements.sql |   62 ++++++
 Open-ILS/web/js/ui/default/actor/user/register.js  |   63 +++++-
 Open-ILS/web/opac/locale/en-US/lang.dtd            |    5 +-
 .../staff_client/server/admin/stat_cat_editor.js   |  223 +++++++++++++++----
 .../server/admin/stat_cat_editor.xhtml             |   60 ++++--
 16 files changed, 674 insertions(+), 91 deletions(-)
 create mode 100644 Open-ILS/src/sql/Pg/upgrade/0701.schema.patron_stat_category_enhancements.sql


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list