+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 ]; }
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();
+
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;
/* 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) )
-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();
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();
/* 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);
}
/* 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 {
my $evt = "environment";
my @COPY_STATUSES;
my @COPY_LOCATIONS;
-my @GROUP_LIST;
+my %GROUP_SET;
+my $GROUP_TREE;
# -----------------------------------------------------------------------
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);
$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;
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;
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;
+
osrf_connect($bsconfig);
-reset_cstore();
#use OpenILS::Utils::ScriptRunner;
#my $r = OpenILS::Utils::ScriptRunner->new;
$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/");
# ---------------------------------------------------------------------
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;
-# 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;
-}