re-organizing, testing, adding functions, adding group configs
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 5 Jul 2006 21:29:06 +0000 (21:29 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 5 Jul 2006 21:29:06 +0000 (21:29 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@4895 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/javascript/backend/circ/circ_lib.js
Open-ILS/src/javascript/backend/circ/circ_permit_copy.js
Open-ILS/src/javascript/backend/circ/circ_permit_hold.js
Open-ILS/src/javascript/backend/circ/circ_permit_patron.js
Open-ILS/src/javascript/backend/penalty/patron_penalty.js
Open-ILS/src/perlmods/OpenILS/Application/Circ/ScriptBuilder.pm
Open-ILS/src/support-scripts/test-scripts/circ_rules.pl

index 0afca26..cbcf0d7 100644 (file)
@@ -1,8 +1,68 @@
+load_lib('../catalog/record_type.js');
+load_lib('../circ/circ_groups.js');
+
+/* ----------------------------------------------------------------------------- 
+       Collect all of the global variables
+       ----------------------------------------------------------------------------- */
+
+/* the global result object.  Any data returned to the 
+       caller must be put into this object.  */
+var result                             = environment.result = {};
+result.event                   = 'SUCCESS';
+result.events                  = [];
+result.fatalEvents     = [];
+result.infoEvents              = [];
+
+
+/* Pull in any variables passed in from the calling process */
+var copy                                       = environment.copy;
+var volume                             = environment.volume;
+var title                              = environment.title;
+var recDescriptor              = environment.titleDescriptor;
+var patron                             = environment.patron;
+var isRenewal                  = environment.isRenewal;
+var patronItemsOut     = environment.patronItemsOut;
+var patronOverdueCount = environment.patronOverdueCount;
+var patronFines                = environment.patronFines;
+
+
+
+/* create some new vars based on the data we have wherever possible */
+var patronProfile;
+var copyStatus;
+var marcXMLDoc;
+
+if( patron && patron.profile ) 
+       patronProfile = patron.profile.name;
+if( copy && copy.status ) 
+       copyStatus = copy.status.name;
+if( title && title.marc )
+       marcXMLDoc = new XML(title.marc);
+
+
+
+
+/* copy the group tree into some other useful data structures */
+var groupTree          = environment.groupTree;
+var groupList          = {};
+var groupIDList        = {};
+flattenGroupTree(groupTree);
+
+
+
+
+
+
+
+/* ----------------------------------------------------------------------------- 
+       Define all of the utility functions
+       ----------------------------------------------------------------------------- */
+
 
-var __scratchKey = 0;
-var __SCRATCH = {};
 
 /* useful functions for creating wrappers around system functions */
+var __scratchKey = 0;
+var __SCRATCH = {};
 function scratchKey()          { return '_' + __scratchKey++; };
 function scratchPad(key)       { return '__SCRATCH.'+ key; }
 function getScratch(key)       { return __SCRATCH[ key ]; }
@@ -19,29 +79,77 @@ function isTrue(d) {
        return false;
 }
 
+/* Utility function for iterating over array */
+function iterate( arr, callback ) {
+       for( var i = 0; i < arr.length; i++ ) 
+               callback(arr[i]);
+}
+
+
+/**
+  * returns a list of items that when passed to the callback 
+  * 'func' returned true returns null if none were found
+  */
+function grep( arr, func ) {
+       var results = [];
+       iterate( arr, 
+               function(d) {
+                       if( func(d) ) 
+                               results.push(d);
+               }
+       );
+       if(results.length > 0)  
+               return results;
+       return null;
+}
+
+
+
+function flattenGroupTree(node) {
+       if(!node) return null;
+       groupList[node.name] = node;
+       groupIDList[node.id] = node;
+       iterate( node.children,
+               function(n) {
+                       flattenGroupTree(n);
+               }
+       );
+}
+
+
+
+/**
+  * Returns true if 'child' is equal or descends from 'parent'
+  * @param parent The name of the parent group
+  * @param child The name of the child group
+  */
+function isGroupDescendant( parent, child ) {
+       return __isGroupDescendant(
+               groupList[parent],
+               groupList[child]);
+}
+
+
+
+/**
+  * Returns true if 'child' is equal or descends from 'parent'
+  * @param parent The node of the parent group
+  * @param child The node of the child group
+  */
+function __isGroupDescendant( parent, child ) {
+       if (parent.id == child.id) return true;
+       var node = child;
+       while( (node = groupIDList[node.parent]) ) {
+               if( node.id == parent.id ) 
+                       return true;
+       }
+       return false;
+}
 
 
-/* collect the useful variables */
-var result                             = environment.result = {};
-result.event                   = 'SUCCESS';
-result.events                  = [];
-result.fatalEvents     = [];
-result.infoEvents              = [];
 
-var copy                                       = environment.copy;
-var volume                             = environment.volume;
-var title                              = environment.title;
-var recDescriptor              = environment.titleDescriptor;
-var patron                             = environment.patron;
-var isRenewal                  = environment.isRenewal;
-var patronItemsOut     = environment.patronItemsOut;
-var patronOverdueCount = environment.patronOverdueCount;
-var patronFines                = environment.patronFines;
-var patronProfile;
-var copyStatus;
 
-if( patron.profile ) patronProfile = patron.profile.name.toLowerCase();
-if( copy.status ) copyStatus = copy.status.name.toLowerCase();
+       
 
 
 
@@ -63,6 +171,7 @@ function log_vars( prefix ) {
                str += ' Patron=' + patron.id;
                str += ', Patron Barcode='      + patron.card.barcode;
                str += ', Patron Username='+ patron.usrname;
+               str += ', Patron Profile Group='+ patronProfile;
                str += ', Patron Library='      + patron.home_ou.name;
                str += ', Patron Fines='        + patronFines;
                str += ', Patron OverdueCount=' + patronOverdueCount;
index f63a057..d9c3761 100644 (file)
@@ -2,8 +2,10 @@ function go() {
 
 /* load the lib script */
 load_lib('circ_lib.js');
-log_vars('circ_permit_copy');
+load_lib('circ_groups.js');
+load_lib('../catalog/record_type.js');
 
+log_vars('circ_permit_copy');
 
 
 if( ! isTrue(copy.circulate) ) 
@@ -14,18 +16,20 @@ if( isTrue(copy.ref) )
 
 
 
-if(copyStatus != 'available' && 
-       copyStatus != 'on holds shelf' && copyStatus != 'reshelving' ) {
+if(copyStatus != 'Available' && 
+       copyStatus != 'On holds shelf' && copyStatus != 'Reshelving' ) {
                result.events.push('COPY_NOT_AVAILABLE');
 }
 
-/* this should happen very rarely .. but it needs to be protected */
-if( recDescriptor.item_type == 'g'  /* projected medium */
+var type = extractFixedField(marcXMLDoc, 'Type');
+log_stdout('type = ' + type);
+
+/* this should happen very rarely .. but it should at least require an override */
+if( extractFixedField(marcXMLDoc, 'Type') == 'g' 
        && copy.circ_lib != patron.home_ou.id )
        result.events.push('CIRC_EXCEEDS_COPY_RANGE');
 
 
-
        
 } go();
 
index f77e51d..e871a80 100644 (file)
@@ -2,17 +2,18 @@
 function go() {
 
 load_lib('circ_lib.js');
+load_lib('circ_groups.js');
+load_lib('../catalog/record_type.js');
 log_vars('circ_permit_hold');
 
 
 
-if( recDescriptor.item_type == 'g'  /* projected medium */
+/* projected medium */
+if( extractFixedField(marcXMLDoc, 'Type') == 'g' 
        && copy.circ_lib != patron.home_ou.id )
-       return result.event = 'CIRC_EXCEEDS_COPY_RANGE';
+       result.events.push('CIRC_EXCEEDS_COPY_RANGE');
 
 
-return result.event = 'SUCCESS';
-
 
 } go();
 
index 1f30374..a7748d7 100644 (file)
@@ -2,38 +2,27 @@ function go() {
 
 /* load the script library */
 load_lib('circ_lib.js');
+load_lib('circ_groups.js');
+
 log_vars('circ_permit_patron');
 
 
-/* make sure they are not barred */
+
 if( isTrue(patron.barred) ) 
        result.events.push('PATRON_BARRED');
 
 
-/* ---------------------------------------------------------------------
-       Set up the limits for the various profiles.
-       values of -1 mean there is no limit 
-       --------------------------------------------------------------------- */
-var PROFILES = {};
-PROFILES['class']                      = { itemsOutLimit : 10 };
-PROFILES['patrons']            = { itemsOutLimit : 10 };
-PROFILES['restricted'] = { itemsOutLimit : 2 };
-PROFILES['circulators'] = { itemsOutLimit : -1 };
-PROFILES['local system administrator'] = { itemsOutLimit : -1 };
-/* add profiles as necessary ... */
-
-
 
 
 /* ---------------------------------------------------------------------
        Check the items out count 
        --------------------------------------------------------------------- */
-var profile = PROFILES[patronProfile];
-if( profile ) {
-       if( patronItemsOut > 0 && patronItemsOut > profile.itemsOutLimit )
+var config = findGroupConfig(patronProfile);
+if( config ) {
+       if( patronItemsOut >= 0 && patronItemsOut > config.maxIitemsOut )
                result.events.push('PATRON_EXCEEDS_CHECKOUT_COUNT');
 } else {
-       log_warn("profile has no configured information: " + patronProfile);
+       log_warn("** profile has no configured information: " + patronProfile);
 }
 
 
index 530eff3..e82752b 100644 (file)
@@ -2,27 +2,20 @@ function go() {
 
 /* load the lib script */
 load_lib('../circ/circ_lib.js');
+load_lib('../catalog/record_type.js');
+load_lib('../circ/circ_groups.js');
 log_vars('patron_penalty');
 
+var config = findGroupConfig(patronProfile);
 
-var PROFILES = {};
-PROFILES['class']                      = { fineLimit : 10, overdueLimit : 10 };
-PROFILES['patrons']            = { fineLimit : 10, overdueLimit : 10 };
-PROFILES['restricted'] = { fineLimit : 0, overdueLimit : 0 };
-PROFILES['circulators'] = { fineLimit : -1, overdueLimit : -1 };
-PROFILES['local system administrator'] = { fineLimit : -1, overdueLimit : -1 };
-/* add profiles as necessary ... */
-
-var profile = PROFILES[patronProfile];
-
-if( profile ) {
+if( config ) {
 
        /* check the fine limit */
-       if( profile.fineLimit > 0 && patronFines >= profile.fineLimit )
+       if( config.fineLimit >= 0 && patronFines >= config.fineThreshold ) 
                result.fatalEvents.push('PATRON_EXCEEDS_FINES');
 
        /* check the overdue limit */
-       if( profile.overdueLimit > 0 && patronOverdueCount > profile.overdueLimit )
+       if( config.overdueLimit >= 0 && patronOverdueCount >= config.overdueThreshold )
                result.fatalEvents.push('PATRON_EXCEEDS_OVERDUE_COUNT');
 
 } else {
index 6a60321..8dd4cb1 100644 (file)
@@ -11,7 +11,8 @@ use Data::Dumper;
 my $evt = "environment";
 my @COPY_STATUSES;
 my @COPY_LOCATIONS;
-my @GROUP_LIST;
+my %GROUP_SET;
+my $GROUP_TREE;
 
 
 # -----------------------------------------------------------------------
@@ -53,6 +54,8 @@ sub build_runner {
        my $ctx         = shift;
        my $runner      = OpenILS::Utils::ScriptRunner->new;
 
+       $runner->insert( "$evt.groupTree",      $GROUP_TREE, 1);
+
        $runner->insert( "$evt.patron",         $ctx->{patron}, 1);
        $runner->insert( "$evt.copy",                   $ctx->{copy}, 1);
        $runner->insert( "$evt.volume",         $ctx->{volume}, 1);
@@ -64,13 +67,6 @@ sub build_runner {
        $runner->insert( "$evt.patronOverdueCount", $ctx->{patronOverdue}, 1 );
        $runner->insert( "$evt.patronFines", $ctx->{patronFines}, 1 );
 
-       # circ script result
-       #$runner->insert("result", {});
-       #$runner->insert("result.event", 'SUCCESS');
-       #$runner->insert("result.events", []);
-       #$runner->insert('result.fatalEvents', []);
-       #$runner->insert('result.infoEvents', []);
-
        $runner->insert("$evt.$_", $ctx->{_direct}->{$_}) for keys %{$ctx->{_direct}};
 
        $ctx->{runner} = $runner;
@@ -164,15 +160,27 @@ sub fetch_user_data {
                unless ref $patron->home_ou;
 
 
-       if(!@GROUP_LIST) {
-               my $s = $e->retrieve_all_permission_grp_tree();
-               @GROUP_LIST = @$s;
+       if(!%GROUP_SET) {
+               $GROUP_TREE = $e->search_permission_grp_tree(
+                       [
+                               { parent => undef }, 
+                               { 
+                                       flesh => 100,
+                                       flesh_fields => { pgt => ['children'] }
+                               } 
+                       ]
+               )->[0];
+
+               _flatten_groups($GROUP_TREE);
        }
 
-       $patron->profile( 
-               grep { $_->id == $patron->profile } @GROUP_LIST ) 
+       $patron->profile( $GROUP_SET{$patron->profile} )
                unless ref $patron->profile;
 
+#      $patron->profile( 
+#              grep { $_->id == $patron->profile } @GROUP_LIST ) 
+#              unless ref $patron->profile;
+
        $patron->card($e->retrieve_actor_card($patron->card));
 
        $ctx->{requestor} = $ctx->{requestor} || $e->requestor;
@@ -206,5 +214,17 @@ sub fetch_user_data {
        return undef;
 }
 
+
+sub _flatten_groups {
+       my $tree = shift;
+       return undef unless $tree;
+       $GROUP_SET{$tree->id} = $tree;
+       if( $tree->children ) {
+               _flatten_groups($_) for @{$tree->children};
+       }
+}
+
+
 1;
 
+
index 1e79c38..194942d 100644 (file)
@@ -36,7 +36,6 @@ my $path;
 
 osrf_connect($bsconfig);
 
-reset_cstore();
 
 #use OpenILS::Utils::ScriptRunner;
 #my $r = OpenILS::Utils::ScriptRunner->new;
@@ -72,7 +71,9 @@ $runner->insert(log_debug             => sub { print "@_\n"; return 1;} );
 $runner->insert(log_internal   => sub { print "@_\n"; return 1;} );
 
 
+$runner->add_path('/openils/var/web/opac/common/js');
 $runner->add_path($path);
+$runner->add_path("$path/../catalog/");
 
 
 # ---------------------------------------------------------------------
@@ -100,13 +101,8 @@ print "events = @$events\n";
 print "info events = @$ievents\n";
 print "fatal events = @$fevents\n";
 
-#show_events( 'events', $result->{events} );
-#show_events( 'fatal_events', $result->{fatalEvents} ); 
-#show_events( 'info_events', $result->{infoEvents} );
-
 print "\ntime = $end\n";
 
-
 sub show_events {
        my $t = shift;
        my $e = shift;
@@ -124,18 +120,4 @@ print "\n";
 
 
 
-# don't forget these..
-#$runner->insert( "$evt.isRenewal", $is_renewal );
-#$runner->insert( "$evt.isNonCat", $is_non_cat );
-#$runner->insert( "$evt.isHold", $is_hold );
-#$runner->insert( "$evt.nonCatType", $non_cat_type );
-
-
-sub reset_cstore {
-       my ($key) = grep { $_ =~ /CStoreEditor/o } keys %INC;
-       delete $INC{$key};
-       no warnings;
-       require OpenILS::Utils::CStoreEditor;
-       use warnings;
-}