[open-ils-commits] r10248 - trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ

svn at svn.open-ils.org svn at svn.open-ils.org
Mon Aug 4 13:14:17 EDT 2008


Author: erickson
Date: 2008-08-04 13:14:09 -0400 (Mon, 04 Aug 2008)
New Revision: 10248

Modified:
   trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm
Log:

Added support for using in-database circ checkout and renew policies

Legacy script support is activated by setting legacy_script_support to true in opensrf.xml
(committing example for that next)

Added open-ils.circ.checkout.inspect, which takes patron and item information and returns
the test retults, including the circ policies that would be applied at checkout.  This
only works on in-db policies



Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm	2008-08-04 06:57:05 UTC (rev 10247)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm	2008-08-04 17:14:09 UTC (rev 10248)
@@ -10,6 +10,7 @@
 
 my %scripts;
 my $script_libs;
+my $legacy_script_support = 0;
 
 sub initialize {
 
@@ -26,6 +27,9 @@
     my $pr  = $conf->config_value(  @pfx, 'circ_permit_renew' );
     my $lb  = $conf->config_value(  @pfx2, 'script_path' );
 
+    $legacy_script_support = $conf->config_value(@pfx2, 'legacy_script_support');
+    $legacy_script_support = ($legacy_script_support and $legacy_script_support =~ /true/i);
+
     $logger->error( "Missing circ script(s)" ) 
         unless( $p and $c and $d and $f and $m and $pr );
 
@@ -47,7 +51,9 @@
         "circ recurring fines = $f, " .
         "circ max fines = $m, ".
         "circ renew permit = $pr.  ".
-        "lib paths = @$lb");
+        "lib paths = @$lb. ".
+        "legacy script support = ". ($legacy_script_support) ? 'yes' : 'no'
+        );
 }
 
 
@@ -138,8 +144,16 @@
     method  => "run_method",
     api_name    => "open-ils.circ.checkout.full.override");
 
+__PACKAGE__->register_method(
+    method  => "run_method",
+    api_name    => "open-ils.circ.checkout.inspect",
+    desc => q/
+        Returns the circ matrix test result and, on success, the rule set and matrix test object
+    /
+);
 
 
+
 sub run_method {
     my( $self, $conn, $auth, $args ) = @_;
     translate_legacy_args($args);
@@ -159,13 +173,19 @@
     $circulator->check_penalty_on_renew(1) if
         $circulator->is_renewal and $U->ou_ancestor_setting_value(
             $circulator->editor->requestor->ws_ou, 'circ.renew.check_penalty', $circulator->editor);
-    $circulator->mk_script_runner;
+
+    if($legacy_script_support and not $circulator->is_checkin) {
+        $circulator->mk_script_runner();
+        $circulator->legacy_script_support(1);
+        $circulator->circ_permit_patron($scripts{circ_permit_patron});
+        $circulator->circ_permit_copy($scripts{circ_permit_copy});      
+        $circulator->circ_duration($scripts{circ_duration});             
+        $circulator->circ_permit_renew($scripts{circ_permit_renew});
+    } else {
+        $circulator->mk_env();
+    }
     return circ_events($circulator) if $circulator->bail_out;
 
-    $circulator->circ_permit_patron($scripts{circ_permit_patron});
-    $circulator->circ_permit_copy($scripts{circ_permit_copy});      
-    $circulator->circ_duration($scripts{circ_duration});             
-    $circulator->circ_permit_renew($scripts{circ_permit_renew});
     
     $circulator->override(1) if $api =~ /override/o;
 
@@ -180,6 +200,11 @@
             $circulator->do_checkout();
         }
 
+    } elsif( $api =~ /inspect/ ) {
+        my $data = $circulator->do_inspect();
+        $circulator->editor->rollback;
+        return $data;
+
     } elsif( $api =~ /checkout/ ) {
         $circulator->do_checkout();
 
@@ -209,7 +234,7 @@
         $circulator->editor->commit;
     }
 
-    $circulator->script_runner->cleanup;
+    $circulator->script_runner->cleanup if $circulator->script_runner;
     
     $conn->respond_complete(circ_events($circulator));
 
@@ -229,7 +254,6 @@
 }
 
 
-
 sub translate_legacy_args {
     my $args = shift;
 
@@ -357,6 +381,11 @@
     phone_renewal
     desk_renewal
     retarget
+    circ_test_success
+    matrix_test_result
+    circ_matrix_test
+    circ_matrix_ruleset
+    legacy_script_support
 /;
 
 
@@ -454,7 +483,78 @@
     return ($one) ? 1 : 0;
 }
 
+sub mk_env {
+    my $self = shift;
+    my $e = $self->editor;
 
+    # --------------------------------------------------------------------------
+    # Grab the fleshed copy
+    # --------------------------------------------------------------------------
+    unless($self->is_noncat) {
+        my $copy;
+	    my $flesh = { 
+		    flesh => 2, 
+		    flesh_fields => {acp => ['call_number'], acn => ['record']} 
+	    };
+	    if($self->copy_id) {
+		    $copy = $e->retrieve_asset_copy(
+			    [$self->copy_id, $flesh ]) or return $e->event;
+    
+	    } elsif( $self->copy_barcode ) {
+    
+		    $copy = $e->search_asset_copy(
+			    [{barcode => $self->copy_barcode, deleted => 'f'}, $flesh ])->[0]
+			    or return $e->event;
+	    }
+    
+        if($copy) {
+            $self->copy($copy);
+            $self->volume($copy->call_number);
+            $self->title($self->volume->record);
+            $self->copy->call_number($self->volume->id);
+            $self->volume->record($self->title->id);
+            $self->is_precat(1) if $self->volume->id == OILS_PRECAT_CALL_NUMBER;
+        } else {
+            # We can't renew if there is no copy
+            return $self->bail_on_events(OpenILS::Event->new('ASSET_COPY_NOT_FOUND'))
+                if $self->is_renewal;
+            $self->is_precat(1);
+        }
+    }
+
+
+    # --------------------------------------------------------------------------
+    # Grab the patron
+    # --------------------------------------------------------------------------
+    my $patron;
+    my $p_evt;
+	if( $self->patron_id ) {
+		$patron = $e->retrieve_actor_user($self->patron_id) or $p_evt = $e->event;
+
+	} elsif( $self->patron_barcode ) {
+
+		my $card = $e->search_actor_card( 
+			{barcode => $self->patron_barcode})->[0] or return $e->event;
+
+		$patron = $e->search_actor_user( 
+			{card => $card->id})->[0] or return $e->event;
+
+	} else {
+		if( my $copy = $self->copy ) {
+			my $circs = $e->search_action_circulation(
+				{target_copy => $copy->id, checkin_time => undef});
+
+			if( my $circ = $circs->[0] ) {
+				$patron = $e->retrieve_actor_user($circ->usr)
+					or return $e->event;
+			}
+		}
+	}
+
+    return $self->bail_on_events(OpenILS::Event->new('ACTOR_USER_NOT_FOUND'))
+        unless $self->patron($patron);
+}
+
 # --------------------------------------------------------------------------
 # This builds the script runner environment and fetches most of the
 # objects we need
@@ -530,9 +630,6 @@
     return 1;
 }
 
-
-
-
 # --------------------------------------------------------------------------
 # Does the circ permit work
 # --------------------------------------------------------------------------
@@ -655,6 +752,19 @@
     return [];
 }
 
+my $LEGACY_CIRC_EVENT_MAP = {
+    'actor.usr.barred' => 'PATRON_BARRED',
+    'asset.copy.circulate' =>  'COPY_CIRC_NOT_ALLOWED',
+    'asset.copy.status' => 'COPY_NOT_AVAILABLE',
+    'asset.copy_location.circulate' => 'COPY_CIRC_NOT_ALLOWED',
+    'config.circ_matrix_test.circulate' => 'COPY_CIRC_NOT_ALLOWED',
+    'config.circ_matrix_test.max_items_out' =>  'PATRON_EXCEEDS_CHECKOUT_COUNT',
+    'config.circ_matrix_test.max_overdue' =>  'PATRON_EXCEEDS_OVERDUE_COUNT',
+    'config.circ_matrix_test.max_fines' => 'PATRON_EXCEEDS_FINES',
+    'config.circ_matrix_circ_mod_test' => 'PATRON_EXCEEDS_CHECKOUT_COUNT',
+};
+
+
 # ---------------------------------------------------------------------
 # This pushes any patron-related events into the list but does not
 # set bail_out for any events
@@ -664,50 +774,127 @@
     my $runner      = $self->script_runner;
     my $patronid    = $self->patron->id;
 
-    $self->send_penalty_request() unless
-        $self->is_renewal and not $self->check_penalty_on_renew;
+    my @allevents; 
 
+    if(!$self->legacy_script_support) {
 
-    # ---------------------------------------------------------------------
-    # Now run the patron permit script 
-    # ---------------------------------------------------------------------
-    $runner->load($self->circ_permit_patron);
-    my $result = $runner->run or 
-        throw OpenSRF::EX::ERROR ("Circ Permit Patron Script Died: $@");
+        my $results = $self->run_indb_circ_test;
+        unless($self->circ_test_success) {
+            push(@allevents, OpenILS::Event->new(
+                $LEGACY_CIRC_EVENT_MAP->{$_->{fail_part}})) for @$results;
+        }
 
-    my $patron_events = $result->{events};
-    my @allevents; 
+    } else {
 
-    my $penalties = ($self->is_renewal and not $self->check_penalty_on_renew) ? 
-        [] : $self->gather_penalty_request();
+        $self->send_penalty_request() unless
+            $self->is_renewal and not $self->check_penalty_on_renew;
 
-    push( @allevents, OpenILS::Event->new($_)) for (@$penalties, @$patron_events);
 
+        # --------------------------------------------------------------------- # Now run the patron permit script 
+        # ---------------------------------------------------------------------
+        $runner->load($self->circ_permit_patron);
+        my $result = $runner->run or 
+            throw OpenSRF::EX::ERROR ("Circ Permit Patron Script Died: $@");
+
+        my $patron_events = $result->{events};
+
+        my $penalties = ($self->is_renewal and not $self->check_penalty_on_renew) ? 
+            [] : $self->gather_penalty_request();
+
+        push( @allevents, OpenILS::Event->new($_)) for (@$penalties, @$patron_events);
+    }
+
     $logger->info("circulator: permit_patron script returned events: @allevents") if @allevents;
 
     $self->push_events(@allevents);
 }
 
+sub run_indb_circ_test {
+    my $self = shift;
+    return $self->matrix_test_result if $self->matrix_test_result;
 
+    my $dbfunc = ($self->is_renewal) ? 
+        'action.item_renew_circ_test' : 'action.item_user_circ_test';
+
+    my $results = ($self->matrix_test_result) ? 
+        $self->matrix_test_result : 
+            $self->editor->json_query(
+                {   from => [
+                        $dbfunc,
+                        $self->editor->requestor->ws_ou,
+                        $self->copy->id, 
+                        $self->patron->id,
+                    ]
+                }
+            );
+
+    $self->circ_test_success($U->is_true($results->[0]->{success}));
+    if($self->circ_test_success) {
+        $self->circ_matrix_test(
+            $self->editor->retrieve_config_circ_matrix_test(
+                $results->[0]->{matchpoint}
+            )
+        );
+    }
+
+    if($self->circ_test_success) {
+        $self->circ_matrix_ruleset(
+            $self->editor->retrieve_config_circ_matrix_ruleset([
+                $results->[0]->{matchpoint},
+                {   flesh => 1,
+                    flesh_fields => {
+                        'ccmrs' => ['duration_rule', 'recurring_fine_rule', 'max_fine_rule']
+                    }
+                }
+                ]
+            )
+        );
+    }
+
+    return $self->matrix_test_result($results);
+}
+
+sub do_inspect {
+    my $self = shift;
+    $self->run_indb_circ_test;
+    return {
+        circ_test_success => $self->circ_test_success,
+        matrix_test_result => $self->matrix_test_result,
+        circ_matrix_test => $self->circ_matrix_test,
+        circ_matrix_ruleset => $self->circ_matrix_ruleset
+    };
+}
+
+
 sub run_copy_permit_scripts {
     my $self = shift;
     my $copy = $self->copy || return;
     my $runner = $self->script_runner;
-    
-   # ---------------------------------------------------------------------
-   # Capture all of the copy permit events
-   # ---------------------------------------------------------------------
-   $runner->load($self->circ_permit_copy);
-   my $result = $runner->run or 
-        throw OpenSRF::EX::ERROR ("Circ Permit Copy Script Died: $@");
-   my $copy_events = $result->{events};
 
-   # ---------------------------------------------------------------------
-   # Now collect all of the events together
-   # ---------------------------------------------------------------------
     my @allevents;
-   push( @allevents, OpenILS::Event->new($_)) for @$copy_events;
 
+    if(!$self->legacy_script_support) {
+        my $results = $self->run_indb_circ_test;
+        unless($self->circ_test_success) {
+            push(@allevents, OpenILS::Event->new(
+                $LEGACY_CIRC_EVENT_MAP->{$_->{fail_part}})) for @$results;
+        }
+    } else {
+    
+       # ---------------------------------------------------------------------
+       # Capture all of the copy permit events
+       # ---------------------------------------------------------------------
+       $runner->load($self->circ_permit_copy);
+       my $result = $runner->run or 
+            throw OpenSRF::EX::ERROR ("Circ Permit Copy Script Died: $@");
+       my $copy_events = $result->{events};
+
+       # ---------------------------------------------------------------------
+       # Now collect all of the events together
+       # ---------------------------------------------------------------------
+       push( @allevents, OpenILS::Event->new($_)) for @$copy_events;
+    }
+
     # See if this copy has an alert message
     my $ae = $self->check_copy_alert();
     push( @allevents, $ae ) if $ae;
@@ -843,7 +1030,7 @@
     }
 
     if( $self->is_precat ) {
-        $self->script_runner->insert("environment.isPrecat", 1, 1);
+        #$self->script_runner->insert("environment.isPrecat", 1, 1)
         $self->make_precat_copy;
         return if $self->bail_out;
 
@@ -1009,27 +1196,47 @@
     my $self = shift;
 
     my $evt;
-   my $runner = $self->script_runner;
-   $runner->load($self->circ_duration);
+    my $runner = $self->script_runner;
 
-   my $result = $runner->run or 
-        throw OpenSRF::EX::ERROR ("Circ Duration Script Died: $@");
+    my $duration;
+    my $recurring;
+    my $max_fine;
+    my $duration_name;
+    my $recurring_name;
+    my $max_fine_name;
 
-   my $duration   = $result->{durationRule};
-   my $recurring  = $result->{recurringFinesRule};
-   my $max_fine   = $result->{maxFine};
+    if(!$self->legacy_script_support) {
+        $self->run_indb_circ_test();
+        $duration = $self->circ_matrix_ruleset->duration_rule;
+        $recurring = $self->circ_matrix_ruleset->recurring_fine_rule;
+        $max_fine = $self->circ_matrix_ruleset->max_fine_rule;
 
-    if( $duration ne OILS_UNLIMITED_CIRC_DURATION ) {
+    } else {
 
-        ($duration, $evt) = $U->fetch_circ_duration_by_name($duration);
-        return $self->bail_on_events($evt) if $evt;
-    
-        ($recurring, $evt) = $U->fetch_recurring_fine_by_name($recurring);
-        return $self->bail_on_events($evt) if $evt;
-    
-        ($max_fine, $evt) = $U->fetch_max_fine_by_name($max_fine);
-        return $self->bail_on_events($evt) if $evt;
+       $runner->load($self->circ_duration);
 
+       my $result = $runner->run or 
+            throw OpenSRF::EX::ERROR ("Circ Duration Script Died: $@");
+
+       $duration_name   = $result->{durationRule};
+       $recurring_name  = $result->{recurringFinesRule};
+       $max_fine_name   = $result->{maxFine};
+    }
+
+    $duration_name = $duration->name if $duration;
+    if( $duration_name ne OILS_UNLIMITED_CIRC_DURATION ) {
+
+        unless($duration) {
+            ($duration, $evt) = $U->fetch_circ_duration_by_name($duration_name);
+            return $self->bail_on_events($evt) if $evt;
+        
+            ($recurring, $evt) = $U->fetch_recurring_fine_by_name($recurring_name);
+            return $self->bail_on_events($evt) if $evt;
+        
+            ($max_fine, $evt) = $U->fetch_max_fine_by_name($max_fine_name);
+            return $self->bail_on_events($evt) if $evt;
+        }
+
     } else {
 
         # The item circulates with an unlimited duration
@@ -1244,7 +1451,7 @@
 
     # this is a little bit of a hack, but we need to 
     # get the copy into the script runner
-    $self->script_runner->insert("environment.copy", $copy, 1);
+    $self->script_runner->insert("environment.copy", $copy, 1) if $self->script_runner;
 }
 
 
@@ -2043,20 +2250,32 @@
 
 sub run_renew_permit {
     my $self = shift;
-   my $runner = $self->script_runner;
 
-   $runner->load($self->circ_permit_renew);
-   my $result = $runner->run or 
-        throw OpenSRF::EX::ERROR ("Circ Permit Renew Script Died: $@");
-   my $events = $result->{events};
+    my $events = [];
 
-   $logger->activity("ciculator: circ_permit_renew for user ".
+    if(!$self->legacy_script_support) {
+        my $results = $self->run_indb_circ_test;
+        unless($self->circ_test_success) {
+            push(@$events, $LEGACY_CIRC_EVENT_MAP->{$_->{fail_part}}) for @$results;
+        }
+
+    } else {
+
+        my $runner = $self->script_runner;
+
+        $runner->load($self->circ_permit_renew);
+        my $result = $runner->run or 
+            throw OpenSRF::EX::ERROR ("Circ Permit Renew Script Died: $@");
+        my $events = $result->{events};
+    }
+
+    $logger->activity("ciculator: circ_permit_renew for user ".
       $self->patron->id." returned events: @$events") if @$events;
 
     $self->push_events(OpenILS::Event->new($_)) for @$events;
-    
+
     $logger->debug("circulator: re-creating script runner to be safe");
-    $self->mk_script_runner;
+    #$self->mk_script_runner;
 }
 
 



More information about the open-ils-commits mailing list