adding penalty server - basically works
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 5 Apr 2006 02:30:42 +0000 (02:30 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 5 Apr 2006 02:30:42 +0000 (02:30 +0000)
and adding initial patron penalty script
updated example file with new penalty app

git-svn-id: svn://svn.open-ils.org/ILS/trunk@3552 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/openils.xml.example
Open-ILS/src/javascript/backend/penalty/patron_penalty.js [new file with mode: 0644]
Open-ILS/src/perlmods/OpenILS/Application/Penalty.pm [new file with mode: 0644]

index b67fe14..0eab842 100644 (file)
@@ -258,6 +258,32 @@ For non-core config info, see the inline documentation within this file
                                </unix_config>
                        </opensrf.dbmath>
 
+
+                       <!-- penalty server -->
+                       <open-ils.penalty> 
+                               <keepalive>3</keepalive>
+                               <stateless>1</stateless>
+                               <language>perl</language>
+                               <implementation>OpenILS::Application::Penalty</implementation>
+                               <max_requests>99</max_requests>
+                               <unix_config>
+                                       <max_requests>1000</max_requests>
+                                       <unix_log>open-ils.penalty_unix.log</unix_log>
+                                       <unix_sock>open-ils.penalty_unix.sock</unix_sock>
+                                       <unix_pid>open-ils.penalty_unix.pid</unix_pid>
+                                       <min_children>5</min_children>
+                                       <max_children>25</max_children>
+                                       <min_spare_children>2</min_spare_children> 
+                                       <max_spare_children>5</max_spare_children>
+                               </unix_config>
+                               <app_settings>
+                                       <patron_penalty>patron_penalty.js</patron_penalty>
+                                       <script_path>/openils/var/penalty/</script_path>
+                               </app_settings>
+                       </open-ils.penalty>
+
+
+
                        <!-- Circulation server -->
                        <open-ils.circ> 
                                <keepalive>3</keepalive>
@@ -373,6 +399,7 @@ For non-core config info, see the inline documentation within this file
                                <appname>open-ils.cat</appname> 
                                <appname>open-ils.search</appname> 
                                <appname>open-ils.circ</appname> 
+                               <appname>open-ils.penalty</appname> 
                                <appname>open-ils.actor</appname> 
                                <appname>open-ils.auth</appname> 
                                <appname>open-ils.storage</appname>  
diff --git a/Open-ILS/src/javascript/backend/penalty/patron_penalty.js b/Open-ILS/src/javascript/backend/penalty/patron_penalty.js
new file mode 100644 (file)
index 0000000..e891324
--- /dev/null
@@ -0,0 +1,39 @@
+function go() {
+
+/* load the lib script */
+load_lib('circ_lib.js');
+
+
+/* collect some useful variables */
+var patron                             = environment.patron;
+var patronProfile              = patron.profile.name.toLowerCase();
+var patronItemsOut     = environment.patronItemsOut;
+var patronFines                = environment.patronFines;
+
+
+log_debug('circ_permit_patron: permit circ on ' +
+       ', Patron:'                                     + patron.id +
+       ', Patron Username:'            + patron.usrname +
+       ', Patron Profile: '            + patronProfile +
+       ', Patron copies: '             + patronItemsOut +
+       ', Patron Library: '            + patron.home_ou.name +
+       ', Patron fines: '              + patronFines +
+       '');
+
+
+if( patronProfile == 'patrons' && patronItemsOut > 10 )
+       result.fatalEvents.push('PATRON_EXCEEDS_CHECKOUT_COUNT');
+
+if( patronProfile == 'staff' && patronItemsOut > 30 )
+       result.fatalEvents.push('PATRON_EXCEEDS_CHECKOUT_COUNT');
+
+
+/* test */
+result.fatalEvents.push('TEST_FATAL_EVENT');
+result.infoEvents.push('TEST_INFO_EVENT');
+/* ---- */
+
+
+} go();
+
+
diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Penalty.pm b/Open-ILS/src/perlmods/OpenILS/Application/Penalty.pm
new file mode 100644 (file)
index 0000000..ff9f5f3
--- /dev/null
@@ -0,0 +1,224 @@
+package OpenILS::Application::Penalty;
+use strict; use warnings;
+use DateTime;
+use Data::Dumper;
+use OpenSRF::EX qw(:try);
+use OpenSRF::Utils::Cache;
+use OpenSRF::Utils qw/:datetime/;
+use OpenILS::Utils::ScriptRunner;
+use OpenSRF::Utils::SettingsClient;
+use OpenILS::Application::AppUtils;
+use OpenSRF::Utils::Logger qw(:logger);
+use base 'OpenSRF::Application';
+
+my $U = "OpenILS::Application::AppUtils";
+my $script;
+my $path;
+my $libs;
+my $runner;
+my %groups; # - user groups
+
+my $fatal_key = 'result.fatalEvents';
+my $info_key = 'result.infoEvents';
+
+
+# --------------------------------------------------------------
+# Loads the config info
+# --------------------------------------------------------------
+sub initialize {
+
+       my $conf = OpenSRF::Utils::SettingsClient->new;
+       my @pfx  = ( "apps", "open-ils.penalty","app_settings" );
+       $path           = $conf->config_value( @pfx, 'script_path');
+       $script = $conf->config_value( @pfx, 'patron_penalty' );
+
+       if(!($path and $script)) {
+               $logger->error("Penalty server config missing script and/or script path");
+               return 0;
+       }
+
+       $logger->info("penalty: Loading patron penalty script $script with path $path");
+}
+
+
+# --------------------------------------------------------------
+# Builds the script runner and shoves data into the script 
+# context
+# --------------------------------------------------------------
+sub build_runner {
+
+       my %args = @_;
+       my $patron = $args{patron};
+       my $patron_summary = $args{patron_summary};
+
+       my $pgroup = find_profile($patron);
+       $patron->profile( $pgroup );
+
+       if($runner) {
+               $runner->refresh_context if $runner;
+
+       } else {
+               $runner = OpenILS::Utils::ScriptRunner->new unless $runner;
+               $runner->add_path( $_ );
+       }
+
+       $runner->insert( 'environment.patron',  $patron, 1);
+       $runner->insert( $fatal_key, [] );
+       $runner->insert( $info_key, [] );
+       $runner->insert( 'environment.patronItemsOut', $patron_summary->[0] );
+       $runner->insert( 'environment.patronFines', $patron_summary->[1] );
+
+       return $runner;
+}
+
+
+sub find_profile {
+       my $patron = shift;
+
+       if(!%groups) {
+               my $groups = $U->storagereq(
+                       'open-ils.storage.direct.permission.grp_tree.retrieve.all.atomic');
+               %groups = map { $_->id => $_ } @$groups;
+       }
+
+       return $groups{$patron->profile};
+}
+
+
+
+__PACKAGE__->register_method (
+       method   => 'patron_penalty',
+       api_name         => 'open-ils.penalty.patron_penalty.calculate',
+       signature => q/
+               Calculates the patron's standing penalties
+               @param authtoken The login session key
+               @params args An object of named params including:
+                       patronid The id of the patron
+                       update True if this call should update the database
+                       background True if this call should return immediately,
+                               then go on to process the penalties.  This flag
+                               works only in conjunction with the 'update' flag.
+               @return An object with keys 'fatal_penalties' and 
+               'info_penalties' who are themeselves arrays of 0 or 
+               more penalties.  Returns event on error.
+       /
+);
+
+# --------------------------------------------------------------
+# modes: 
+#  - update 
+#  - background : modifier to 'update' which says to return 
+#              immediately then continue processing.  If this flag is set
+#              then the caller will get no penalty info and will never 
+#              know for sure if the call even succeeded. 
+# --------------------------------------------------------------
+sub patron_penalty {
+       my( $self, $conn, $authtoken, $args ) = @_;
+       
+       my( $requestor, $patron, $evt );
+
+       $conn->respond_complete(1) if $$args{background};
+
+       ( $patron, $evt ) = $U->fetch_user($$args{patronid});
+       return $evt if $evt;
+
+       ( $requestor, $evt ) = $U->checkses($authtoken);
+       return $evt if $evt;
+
+       $evt = $U->check_perms( $requestor->id,  $patron->home_ou, 'VIEW_USER');
+       return $evt if $evt;
+
+       # - fetch the circulation summary info for the user
+       my $summary = $U->fetch_patron_circ_summary($patron->id);
+
+       # - build the script runner
+       my $runner = build_runner( 
+               patron                  => $patron, 
+               patron_summary => $summary 
+               );
+
+       # - Load up the script and run it
+       $runner->add_path($path);
+       $runner->load($script);
+       $runner->run or throw OpenSRF::EX::ERROR ("Patron Penalty Script Died: $@");
+
+       # array items are returned as a comma-separated list of strings
+       my @fatals = split( /,/, $runner->retrieve($fatal_key) );
+       my @infos = split( /,/, $runner->retrieve($info_key) );
+       my $all = [ @fatals, @infos ];
+
+       $logger->info("penalty: script returned fatal events [@fatals] and info events [@infos]");
+
+       # - update the penalty info in the db if necessary
+       $evt = update_patron_penalties( 
+               patron    => $patron, 
+               penalties => $all, 
+               requestor => $requestor ) if $$args{update};
+
+       return $evt if $evt;
+
+       return { fatal_penalties => \@fatals, info_penalties => \@infos };
+}
+
+# --------------------------------------------------------------
+# Removes existing penalties for the patron that are not passed 
+# into this function.  Creates new penalty entries for the 
+# provided penalties that don't already exist;
+# --------------------------------------------------------------
+sub update_patron_penalties {
+
+       my %args      = @_;
+       my $patron    = $args{patron};
+       my $penalties = $args{penalties};
+       my $requestor = $args{requestor};
+
+       my $session   = $U->start_db_session();
+
+       # - fetch the current penalties
+       my $existing = $session->request(
+               'open-ils.storage.direct.actor.'.
+               'user_standing_penalty.search.usr.atomic', $patron->id )->gather(1);
+
+       my @deleted;
+       my $reqid = $requestor->id;
+       my $patronid = $patron->id;
+
+       # If an existing penalty is not in the newly generated 
+       # list of penalties, remove it from the DB
+       for my $e (@$existing) {
+               if( ! grep { $_ eq $e->penalty_type } @$penalties ) {
+
+                       $logger->activity("user $reqid removing user penalty ".
+                               $e->penalty_type . " from user $patronid");
+
+                       my $s = $session->request(
+                               'open-ils.storage.direct.actor.user_standing_penalty.delete', $e->id )->gather(1);
+                       return $U->DB_UPDATE_FAILED($e) unless defined($s);
+               }
+       }
+
+       # Add penalties that previously didn't exist
+       for my $p (@$penalties) {
+               if( ! grep { $_->penalty_type eq $p } @$existing ) {
+
+                       $logger->activity("user $reqid adding user penalty $p to user $patronid");
+
+                       my $newp = Fieldmapper::actor::user_standing_penalty->new;
+                       $newp->penalty_type( $p );
+                       $newp->usr( $patronid );
+
+                       my $s = $session->request(
+                               'open-ils.storage.direct.actor.user_standing_penalty.create', $newp )->gather(1);
+                       return $U->DB_UPDATE_FAILED($p) unless $s;
+               }
+       }
+       
+       $U->commit_db_session($session);
+       return undef;
+}
+
+
+
+
+
+1;